js精度丢失


  • JS采数字采用IEEE 754 双精度 64 位浮点数来存储,只能保存小数点52位,53位为0省略,53位为1进1

  • 0.2 + 0.1 = 0.3 ?

  • 0.1 = 0.0001100110011001100110011001100110011001100110011001100

  • 0.2 = 0.00110011001100110011001100110011001100110011001100110011

  • 0.3 = 0.01001100110011001100110011001100110011001100110011001100


因为,只能保存小数点52位,53位为0省略,53位为1进1

  • 0.1 = 0.0001100110011001100110011001100110011001100110011011
  • 0.2 = 0.0011001100110011001100110011001100110011001100110011
  • 0.1 + 0.2 = 0.0100110011001100110011001100110011001100110011001110
  • 0.3 = 0.0100110011001100110011001100110011001100110011001101

所以,0.1 + 0.2 !== 0.3

控制台输出可见,0.1 + 0.2 = 0.30000000000004,与0.3的差值无限接近与0

那么应该怎样来判断0.1 + 0.2和0.3是否相等呢?

最常见的方法是设置一个误差范围值,这个值通常是2^-52

ES6 存在 Number.EPSILON,代表一个很小的数,如果某个数小于等于这个值,则误差可以忽略不计

兼容ES6之前的版本写polyfill

if ( !Number.EPSILON ) {
	Number.EPSILON = Math.pow(2, -52)
}
Math.abs(0.3 - (0.1 + 0.2)) <= Number.EPSILON // true