0


JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js

一、计算精度现象举例

举例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.4636476090008061log返回给定数字的自然Log值(即e的底数)
log(9)
2.1972245773362196
pi
圆周率
console.log('pi:', pi)
3.141592653589793e欧拉常数和自然对数的基数,约为 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 参考手册


本文转载自: https://blog.csdn.net/snowball_li/article/details/129732368
版权归原作者 snow@li 所有, 如有侵权,请联系我们删除。

“JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js”的评论:

还没有评论