1. 前言
- js中小数计算时,时常会出现由于精度问题出现的计算结果有误等
- 在JS中不区分整数和小数,因为JS中天生浮点数(双精度),在计算机存储中,双精度的实际存储位数是52位,由于二进制中只有 0 和 1,但52位有时并不能准确的表达小数点后面的数字,在十进制中有四舍五入,在二进制中存在0舍1入,所以当52位无法准确的表达出一个小数时,就会产生补位动作,数值偏差就在这时产生了,这是造成计算精度问题的原因
- 举例 处理类似这类小数转整数也会失精度,所以转整数后再四舍五入取整下 8969.3 * 100 = 896929.999999999999,18.24 * 100 = 1823.9999999999998
2. 实现
- 将小数部分转为整数只有再进行相关计算
- 封装小数计算方法
function amendVal (num1, num2, symbol) {
let str1 = num1.toString()
let str2 = num2.toString()
let result
let str1Length
let str2Length
try { str1Length = str1.split('.')[1].length } catch (error) { str1Length = 0 }
try { str2Length = str2.split('.')[1].length } catch (error) { str2Length = 0 }
var step = Math.pow(10, Math.max(str1Length, str2Length))
num1 = Math.round(num1 * step)
num2 = Math.round(num2 * step)
switch (symbol) {
case '+':
result = (num1 + num2) / step
break
case '-':
result = (num1 - num2) / step
break
case '*':
result = (num1 * num2) / step / step
break
case '/':
result = num1 / num2
break
default:
break
}
return result
}
3. 效果
const val = 18.24 * 100
const val1 = amendVal(18.2, 100, '*')
console.log('按小数直接运算结果', val)
console.log('将小数部分转为整数在运算', val1)