问题:
计算10057.2 / 6.7048的结果,计算机的结果为1500,代码计算的结果为1500.0000000000002;很明显代码计算的结果出现了误差问题,导致结果不是我们想要的。
为什么会出现误差?
浮点数值的最高进度是17位小数,但在进行运算的时候其精确度却远远不如整数;整数在进行运算的时候都会转成10进制; 而Java和JavaScript中计算小数运算时,都会先将十进制的小数换算到对应的二进制,一部分小数并不能完整的换算为二进制,这里就出现了第一次的误差。待小数都换算为二进制后,再进行二进制间的运算,得到二进制结果。然后再将二进制结果换算为十进制,这里通常会出现第二次的误差。
解决办法:自定义计算方法
//除法:
//调用:accDiv(arg1,arg2)
//返回值:arg1除以arg2的精确结果
export function accDiv(arg1, arg2) {
let t1 = 0,
t2 = 0,
r1,
r2
try {
t1 = arg1.toString().split('.')[1].length
} catch (e) {}
try {
t2 = arg2.toString().split('.')[1].length
} catch (e) {}
r1 = Number(arg1.toString().replace('.', ''))
r2 = Number(arg2.toString().replace('.', ''))
return (r1 / r2) * Math.pow(10, t2 - t1)
}
//乘法:
//调用:accDiv(arg1,arg2)
//返回值:arg1乘以arg2的精确结果
export function accMul(arg1, arg2) {
let m = 0,
s1 = arg1.toString(),
s2 = arg2.toString()
try {
m += s1.split('.')[1].length
} catch (e) {}
try {
m += s2.split('.')[1].length
} catch (e) {}
return (
(Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) /
Math.pow(10, m)
)
}
//加法:
//调用:accDiv(arg1,arg2)
//返回值:arg1加上arg2的精确结果
export function accAdd(arg1, arg2) {
let r1, r2, m
try {
r1 = arg1.toString().split('.')[1].length
} catch (e) {
r1 = 0
}
try {
r2 = arg2.toString().split('.')[1].length
} catch (e) {
r2 = 0
}
m = Math.pow(10, Math.max(r1, r2))
return (arg1 * m + arg2 * m) / m
}
//减法:
//调用:accDiv(arg1,arg2)
//返回值:arg1减去arg2的精确结果
export function accSubtr(arg1, arg2) {
let r1, r2, m, n
try {
r1 = arg1.toString().split('.')[1].length
} catch (e) {
r1 = 0
}
try {
r2 = arg2.toString().split('.')[1].length
} catch (e) {
r2 = 0
}
m = Math.pow(10, Math.max(r1, r2))
//动态控制精度长度
n = r1 >= r2 ? r1 : r2
return ((arg1 * m - arg2 * m) / m).toFixed(n)
}