Skip to content
On this page

数字精度计算

为什么会出现精度缺失

这是 JavaScript 由来已久的问题:0.1 + 0.2 != 0.3

计算机的存储是用二进制(0和1)表示,所以 0.10.2 都转化成二进制后再进行计算

js
// 0.1 和 0.2 都转化成二进制后再进行运算
0.00011001100110011001100110011001100110011001100110011010 +
0.0011001100110011001100110011001100110011001100110011010 =
0.0100110011001100110011001100110011001100110011001100111

// 转成十进制正好是 0.30000000000000004

所以输出 false

解决方案

一般都是把小数转成整数后再运算

js
/**
 * 精确加法
 */
function add(num1, num2) {
  const num1Digits = (num1.toString().split('.')[1] || '').length;
  const num2Digits = (num2.toString().split('.')[1] || '').length;
  const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));
  return (num1 * baseNum + num2 * baseNum) / baseNum;
}

// add(0.1, 0.2) // 0.3

toFixed 的修复

js
function toFixed(num, s) {
  var times = Math.pow(10, s)
  var des = num * times + 0.5
  des = parseInt(des, 10) / times
  return des + ''
}

// toFixed(1.335, 2) // '1.34'

由于项目对于计算的要求高,还是推荐使用第三方库,如 Math.jsbig.js,这些库经过测试,对于边界情况考虑相对全面一点。