1.在JavaScript计算带有小数的金额时,很容易出现零点几的差距。如果采用的是成10的倍数形式要注意一下某些情况。
如:在JavaScript计算4.055乘1000并不等于4055,而是等于 4054.9999999999995。如果采用直接截取的方式很可能会出现少了0.001的金额。
如果采用先把小数乘10的倍数变成整数的方式,在计算完成后再除以之前10的倍数,这种方式的话建议乘数10的倍数再多一个0。
如:4.055参与计算前把它变成40550,不要变成4055,因为它很可能变成上面的情况少了1的精度。
二次更新:
2.上面的方法1在后面测试过程中还是出现了问题。
如:5.685在变成整数的过程中,5.685乘1000等于5685,
但是根据方法1的方式再加一个0,又出现了问题。
5.685成10000等于56849.99999999999,由于这种不确定性只能灵活的乘10的倍数。
由此在两个小数参与计算之前,先得到这两个小数乘10的多少倍数才都为整数的情况下。再进行计算就不会有问题了。
//小数转换为整数需要乘10的倍数
let multipleNum = 1
//记录动态的乘10倍数
let addMultipleNum = 1
//记录传递的小数最大的小数位数长度
let decimalLength = 0
//返回的结果
let result = 0
decimals.forEach(item => {
let num = item.toString().split('.')
if (num[1] && num[1].length > decimalLength) {
decimalLength = num[1].length
}
})
for (let i = 0; i < decimalLength; i++) {
multipleNum *= 10
}
let x = 0
do {
let numArray = []
decimals.forEach(item => {
numArray.push(item * (multipleNum * addMultipleNum))
})
let isFail = false
for (let i = 0; i < numArray.length; i++) {
if (numArray[i].toString().includes('.')) {
addMultipleNum *= 10
isFail = true
break
}
}
if (isFail) {
x++
} else {
x = 5
}
} while (x < 5)
if (handle == 'add') {//加法
decimals.forEach(item => {
result += item * (multipleNum * addMultipleNum)
})
result = result / (multipleNum * addMultipleNum)
return result
}