Number 的失真边界

Javascript 中的 Number 是个神奇的类型,它模糊了 整形浮点数 之间的边界,当你拿到一个 Number 的时候,它就只是一个 Number,而且可以很方便地表示非常大的数 Number.MAX_VALUE 或者,或者非常小的数 Number.MIN_VALUE。
实际应用场合里面除了要表示大数和小数,有时还会讲究下精度的。

MDN 的 Number.toPrecision 中有描述 ECMA-262 only requires a precision of up to 21 significant digits. Other implementations may not support precisions higher than required by the standard.”

我们可以知道 JavaScript 的精度在 21 位。究竟是不是代表只要少于 21 位的数都能精确表示呢?简单来个试验就可以知道了。可以猛击这个链接 看看你的浏览器里的 js 到底能有多精确

var arr = [];
for(var i = 0; i< 21; i++) {
  arr.push('9');
  console.log((i+1) + ' : ' + arr.join('') + ' >>' + Number(arr.join('')));
}

我在 Firefox 11 上的结果是到 16 位的时候就已经失真了。

如果是小数的情况:

var arr = ['9.'];
for(var i = 0; i< 21; i++) {
  var str = arr.join('') + '9';
  push((i+1) + ' : ' + str, Number(str));
  arr.push('9');
}

同样地,小数位达到 15 位时出现失真。上面的试验用的是 Number() 进行转换,这与手写同样长度的数字效果是一样的。

幸运的是,这些精度基本够用了。但如果哪位仁兄希望用 JavaScript 来处理一些高精度方面的问题,就必须得注意了,其实 15 位已经是一道坎了。