lxinr/interview-question

为什么0.1 + 0.2 === 0.3 结果为false

Opened this issue · 0 comments

lxinr commented

原因

因为Number采用的是IEEE754,64位双精度浮点数编码,因此不仅仅是js,所有使用IEEE754浮点数运算标准的语言都有这样的问题,究其本质可以概括为二进制模拟十进制进行计算时的精度问题,详细可查阅:https://juejin.im/post/5b90e00e6fb9a05cf9080dff

解决方案

使用机器精度(machine epsilon)

对JavaScript 的数字来说,这个值通常是 2^-52 (2.220446049250313e-16)

ES6开始,有一个Number.EPSILON来专门表示这个值,因此可以用这个值来判断是否相等(在指定的误差范围内)

function numbersCloseEnoughToEqual(n1,n2) {
 return Math.abs( n1 - n2 ) < Number.EPSILON
}
const a = 0.1 + 0.2
const b = 0.3
numbersCloseEnoughToEqual( a, b ) // true
numbersCloseEnoughToEqual( 0.0000001, 0.0000002 ) // false

转成整数

const add = (n1, n2) => {
  const dec1 = (('' + n1).split('.')[1] || '').length
  const dec2 = (('' + n2).split('.')[1] || '').length
  const baseN = Math.pow(10, Math.max(dec1, dec2))
  return (n1 * baseN + n2 * baseN) / baseN
}

console.log('add----12-', add(0.1, 0.2)) // 0.3

使用专门的库

Math.jsbig.js