关于js中对小数的计算


例子

  • 在js的小数计算中,0.1+0.2=0.30000000000000004

    let num1 = 0.1;
    let num2 = 0.2;
    
    console.log( num1 + num2 );
    // 0.30000000000000004 

    为什么

  • 为什么出现这样的结果,我们把小数转换成计算机能读得懂的二进制就比较明了了

    // 0.1 -> 0.1.toString(2) -> 0.0001100110011001100110011001100110011001100110011001101(无限循环…)
    // 0.2 -> 0.1.toString(2) -> 0.001100110011001100110011001100110011001100110011001101(无限循环…)
  • 双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串

    • 0.0100110011001100110011001100110011001100110011001100
  • 因浮点数小数位的限制而截断的二进制数字,这时候,我们再把它转换为十进制,就成了 0.30000000000000004

如何处理此类问题?

  • 为了避免产生精度差异,我们要把需要计算的数字乘以 10 的 n 次幂,换算成计算机能够精确识别的整数,然后再除以 10 的 n 次幂,大部分编程语言都是这样处理精度差异的,我们就借用过来处理一下 JS 中的浮点数精度误差。
formatNum = function( num, digit ) {
  let m = Math.pow( 10, digit );
  return parseInt( num * m, 10 ) / m;
}
let num1 = 0.1;
let num2 = 0.2;
console.log( num1 + num2 );
console.log( formatNum( num1 + num2, 1) );
// Tips:
// pow() 方法可返回 x 的 y 次幂的值。
// parseInt() 函数可解析一个字符串,并返回一个整数。(第二个参数取值2-36,省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。)

文章作者: Damao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Damao !
  目录