#2 js中number类型计算精度问题解决
在js数学计算中会遇到一些让人匪夷所思的问题。例如0.2+0.4=0.6000000000000001,显然这个结果在我们的认知中是不正确的。类似的问题乘法等计算都会出现。
如何解决呢?分享一个工具方法
/**
* 解决数字精度出错问题
* @param {*} num1 number类型
* @param {*} num2 number类型
* @param {*} symbol 运算符
* @returns 返回实际结果
*/
export function amendAccuracy(num1, num2, symbol) {
const str1 = num1.toString()
const str2 = num2.toString()
let result, str1Length, str2Length
// 解决整数没有小数点方法
try {
str1Length = str1.split('.')[1].length
} catch (error) {
str1Length = 0
}
try {
str2Length = str2.split('.')[1].length
} catch (error) {
str2Length = 0
}
const step = Math.pow(10, Math.max(str1Length, str2Length))
switch (symbol) {
case '+':
result = (num1 * step + num2 * step) / step
break
case '-':
result = (num1 * step - num2 * step) / step
break
case '*':
result = (num1 * step * (num2 * step)) / (step * step)
break
case '/':
result = (num1 * step) / (num2 * step)
break
default:
break
}
return result
}
探其究竟。为什么会出现此类问题呢,继续往下看。
主要原因是 JavaScript 使用 IEEE 754 标准的双精度浮点数(64 位)来表示所有数字,无论是整数还是浮点数。这种表示方式虽然强大,但也有一些局限性,导致了精度问题的出现。
普遍原因分析:
- 二进制表示的局限性:十进制小数在二进制中可能无法精确表示,导致计算结果出现微小误差。
- 有限的存储空间:浮点数的尾数部分只有 52 位,无法存储无限精度的数字。
- 舍入规则:计算机在处理浮点数时会根据 IEEE 754 标准进行舍入,这可能导致误差累积。
IEEE 754 浮点数的表示方式
IEEE 754 标准将数字表示为 二进制浮点数,其结构分为三个部分:
• 符号位(1 位):表示数字的正负。
• 指数位(11 位):表示数字的大小范围。
• 尾数位(52 位):表示数字的精度。
这种表示方式在处理十进制小数时,可能会导致某些数字无法精确表示。例如,十进制中的 0.1 在二进制中是一个无限循环小数,无法用有限的二进制位精确表示。