JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js
作者:小教学发布时间:2023-09-29分类:程序开发学习浏览:63
一、计算精度现象举例
举例1、加法
举例2、减法
举例3、乘法
举例3、除法
二、JS为什么会有计算精度的问题
JavaScript 内部只有一种数字类型Number,也就是说,JavaScript 语言的底层根本没有整数,所有数字都是以IEEE-754标准格式64位浮点数形式储存,1与1.0是相同的。因为有些小数以二进制表示位数是无穷的。JavaScript会把超出53位之后的二进制舍弃,所以涉及小数的比较和运算要特别小心。
IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number)),一些特殊数值(无穷(Inf)与非数值(NaN)),以及这些数值的“浮点数运算符”;它也指明了四种数值舍入规则和五种例外状况(包括例外发生的时机与处理方式)。
三、解决方法
项目技术栈vue3+vite+ts
3.1、方法一,同时扩大倍数再除以相同的倍数
(x * 10 ^ n + y * 10 ^ n)/ 10 ^ n
0.1 +0.2
// 0.30000000000000004
(0.1 *10 + 0.2 *10) / 10
// 0.3
3.2、方法二,toFixed保留小数位数,依然存在精度问题
3.3、方法三,mathjs - npm
pnpm add mathjs
Weekly Download 580197 (20230324)
方法 | 运算 | 使用 | 运输结果 |
add | 加法 | add(1, 2) | 3 |
subtract | 减法 | subtract(2, 1) | 1 |
multiply | 乘法 | multiply(2, 2) | 4 |
divide | 除法 | divide(4, 2) | 2 |
round | 四舍五入 | round(4.01) | 4 |
bignumber | 转换为bigNumber类型。对于具有任意精度的计算,math.js支持BigNumber数据类型,bignumber返回一个Decimal类,精度依然难以保证 | bignumber(4.01) | |
evaluate | 直接运算表达式 | evaluate('(4.01 + 3) / 2') | 3.505 |
sqrt | 平方根计算 | sqrt(4) | 2 |
pow | x 的 y 次幂值 | pow(3,3) | 27 |
chain | 链式操作 | chain(3).add(4).multiply(2).done() | 14 |
atan2 | 返回其参数商的反正切值 | atan2(15,30) | 0.4636476090008061 |
log | 返回给定数字的自然Log值(即e的底数) | log(9) | 2.1972245773362196 |
pi | 圆周率 | console.log('pi:', pi) | 3.141592653589793 |
e | 欧拉常数和自然对数的基数,约为 2.718 | console.log('e:', e) | 2.718281828459045 |
derivative | 待考证 | console.log('derivative:',derivative('x^2 + x', 'x')) | |
matrix | 矩阵操作 | matrix([0, 1, 2, 3, 4]) |
3.4、方法四,bignumber.js - npm
Weekly Download 8826960 (20230324)
pnpm add bignumber.js
const num = new BigNumber(1234567890.0123456789) | |||
const num1 = new BigNumber(123.123) | |||
方法 | 运算 | 使用 | 运算结果 |
toFormat | 格式化 | num.toFormat() | 1,234,567,890.0123458 保留了七位小数,第七位依据第八位四舍五入 |
toFormat | 格式化 | num.toFormat(3) | 1,234,567,890.012 保留三位小数 |
toFormat | 格式化 | num.toFormat(13) | 1,234,567,890.012 保留十三位小数,实际还是保留了七位小数,第七位依据第八位四舍五入,然后位数用0补足 |
plus | 加法 | num1.plus(1.1) | |
minus | 减法 | num1.minus(1.1) | |
times | 乘法 | num1.times(2) | |
div | 除法 | num1.div(2) | |
mod | 取余 | num1.mod(2) | |
x.eq(y) | isEqualTo--是否相等 | num.eq(num1) | false |
x.gt(y) | isGreaterThan--是否大于 | num.gt(num1) | true |
x.gte(y) | isGreaterThanOrEqualTo--是否大于等于 | num.gte(num1) | true |
x.lt(y) | isLessThan--是否小于 | num.lt(num1) | false |
x.lte(y) | isLessThanOrEqualTo--是否小于等于 | num.lte(num1) | false |
negated | 取非,改变数字的正负号 | num.negated() |
3.5、方法五,big.js - npm
Weekly Download 21,339,420 (20230324)
pnpm add @types/big.js
const num = new Big(1234567890.0123456789) | |||
const num1 = new Big(123.123) | |||
方法 | 运算 | 使用 | 运算结果 |
plus | 加法 | num1.plus(1.1) | |
minus | 减法 | num1.minus(1.1) | |
times | 乘法 | num1.times(2) | |
div | 除法 | num1.div(2) | |
mod | 取余 | num1.mod(2) | |
x.eq(y) | isEqualTo--是否相等 | num.eq(num1) | false |
x.gt(y) | isGreaterThan--是否大于 | num.gt(num1) | true |
x.gte(y) | isGreaterThanOrEqualTo--是否大于等于 | num.gte(num1) | true |
x.lt(y) | isLessThan--是否小于 | num.lt(num1) | false |
x.lte(y) | isLessThanOrEqualTo--是否小于等于 | num.lte(num1) | false |
3.6、方法六,decimal.js - npm
Weekly Download 16,251,713 (20230324)
pnpm add decimal.js
const num = new Big(1234567890.0123456789) | |||
const num1 = new Big(123.123) | |||
方法 | 运算 | 使用 | 运算结果 |
plus | 加法 | num1.plus(new Decimal(1.1)) | |
minus | 减法 | num1.minus(new Decimal(1.1)) | |
times | 乘法 | num1.times(new Decimal(2)) | |
div | 除法 | num1.div(new Decimal(2)) | |
mod | 取余 | num1.mod(new Decimal(2)) | |
x.eq(y) | isEqualTo--是否相等 | num.eq(num1) | false |
x.gt(y) | isGreaterThan--是否大于 | num.gt(num1) | true |
x.gte(y) | isGreaterThanOrEqualTo--是否大于等于 | num.gte(num1) | true |
x.lt(y) | isLessThan--是否小于 | num.lt(num1) | false |
x.lte(y) | isLessThanOrEqualTo--是否小于等于 | num.lte(num1) | false |
四、欢迎交流指正,关注我,一起学习。
参考链接:
JavaScript Math 参考手册
- 程序开发学习排行
-
- 1鸿蒙HarmonyOS:Web组件网页白屏检测
- 2HTTPS协议是安全传输,为啥还要再加密?
- 3HarmonyOS鸿蒙应用开发——数据持久化Preferences
- 4记解决MaterialButton背景颜色与设置值不同
- 5鸿蒙HarmonyOS实战-ArkUI组件(RelativeContainer)
- 6鸿蒙HarmonyOS实战-ArkUI组件(Stack)
- 7鸿蒙HarmonyOS实战-ArkUI组件(GridRow/GridCol)
- 8[Android][NDK][Cmake]一文搞懂Android项目中的Cmake
- 9鸿蒙HarmonyOS实战-ArkUI组件(mediaquery)
- 最近发表
-
- WooCommerce最好的WordPress常用插件下载博客插件模块的相关产品
- 羊驼机器人最好的WordPress常用插件下载博客插件模块
- IP信息记录器最好的WordPress常用插件下载博客插件模块
- Linkly for WooCommerce最好的WordPress常用插件下载博客插件模块
- 元素聚合器Forms最好的WordPress常用插件下载博客插件模块
- Promaker Chat 最好的WordPress通用插件下载 博客插件模块
- 自动更新发布日期最好的WordPress常用插件下载博客插件模块
- WordPress官方最好的获取回复WordPress常用插件下载博客插件模块
- Img to rss最好的wordpress常用插件下载博客插件模块
- WPMozo为Elementor最好的WordPress常用插件下载博客插件模块添加精简版