You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What is the result of this expression? (or multiple ones)
var end = Math.pow(2, 53);
var START = end - 100;
var count = 0;
for (var i = START; i <= end; i++) {
count++;
}console.log(count);
A:0B:100C:101D:other
答案:D:other
it goes into an infinite loop, 2^53 is the highest possible number in javascript, and 2^53+1 gives 2^53, so i can never become larger than that.
本文来自对http://javascript-puzzlers.herokuapp.com/ 相关的精度问题的探索,并尝试着以一个数轴链接一些关于Number,关于数字表示的知识点。欢迎帮忙捉虫、补充。
从题目开始
这里答案的解释比较让人混淆,让我们深入到内存模型,来看看Number的表示上下限的由来。
数轴
说明
Number.MAX_VALUE
和Number.MIN_VALUE
:这个结果为了好看被我四舍五入了……关于Number表示的内存模型
参考国际标准IEEE 754,我画了一张图帮助理解:
注,这里的字符是从左到右排的,和wiki之类的资料顺序相反。wiki资料考虑的是比较的顺序(符号-指数位-有效数字),而我这里考虑到的是阅读顺序(从0到63位,从左到右)。
中间的指数位是如何同时表示正负指数值的呢,和“符号位+有效数字位”的常规表示方法不同,指数是使用偏移法来做的:
因此,在JavaScript里面的指数位,是从1-2^(11-1),也就是从-1023开始,表示了(-1023,1024)这个区间。
Number保留了指数值0和2047用于表示一些特殊的值。总的表示表格如下:
f(i,j,k) = (-1)k · 2-1023+j · i
精确表示到个位的最大整数
前52位能表示的最大值是下面这个(下面是52位+1位默认的1):
而下一个值是:
根据内存模型,画一张图就可以知道:
从第2^53位开始,第一个进制被舍弃,这个时候,2^53+1==2^53,每两个值都会有一个值出现这种不精确的情形。再过N个值,会出现每4个值里面都有3个值不精确;再过M个值,会出现每2^K个值里有2^K-1个值不精确;以此类推……(小题目:这个N值是多少?)
最大可表示的正数
验证:
QED
最小可表示的正数
还记得前面的表格吗:
f(i,j,k) = (-1)k · 2-1023+j · i
非规格化值是这样表示的:
最小正数的内存模型
验证:
参考资料
除了IEEE 754的维基页面,还有这篇文章,解释的非常清晰:"How numbers are encoded in JavaScript"
The text was updated successfully, but these errors were encountered: