var a = 11111111111111111111 打印结果求解答

var a = 11111111111111111111;
console.log(a);
//chrome : 11111111111111110000 
//nodejs : 11111111111111110000

求大神解释,为什么会打印出不相符的结果?

阅读 4k
6 个回答

这个跟计算机中用于存储数字的方法有关. 你想想, 你这个整数都已经那么大啦, 忽略了那几百大小, 又有什么影响呢? 至于这是像IEEE754不能存储0.3那样的原因, 还是为了节省开销, 我也不清楚. 不过我们可以来做一个有趣的实验.

在控制台输入Number.MAX_VALUE, 打印出的数字是1.7976931348623157e+308, 注意数他的有效数字位数, 是17. 你试着打印179769313486231571, 最后添加的1也会变成0, 输入1234567890123456789, 会输出1234567890123456800, 可见17是他能达到的最大位数, 再大就会被置为0. 再看你的a, 是16位, 为什么呢? 可能是因为单身狗比较特殊.

浮点数范围:
±1.7976931348623157 × 10的308次方
±5 × 10的−324次方

精确整数范围:
The JavaScript number format allows you to exactly represent all integers between
−9007199254740992 and 9007199254740992 (即正负2的53次方)

科普文章:
https://developer.mozilla.org...

https://segmentfault.com/a/11...

多余的位数被改成0是因为最大位数的原因导致的.
刚才试了几个比较特殊的,比如:

var a = 11111111111111111;
console.log(a);
11111111111111112

IEEE754 64位浮点数只能保存 15~16 位有效数字...

具体来说,一个浮点数f(正则数),会被表示为:f = s* m *2^e
其中s为 +1 或是 -1,m 为满足某个条件的小数(见下面),e有符号整数。
其中s占1bit,m占52bit,e占11bit,共64bit。

其实,把f分解为上述形式在二进制数的运算里更方便。
现在我们用二进制的数来表示 mm被化为二进制数之后最高为肯定为1(二进制数只有0 1 而最高位的0 我们通常不写)。通过移动小数点,我们可以把 m 写为1+p 其中 p 是小于 1 的非负数。由于最高位固定为 1 所以可以用 52bit 表示 p。也就是我们其实用 53bit 表示了 m,虽然 m 只占用了 52bit。所以对于(正则)浮点数,IEEE 745 只能保存 53 个有效bit,

比如个 var a 二进制表示为(1001101000110010100110001010111110110101101011000111000111000111)
(+1) × (1.001101000110010100110001010111110110101101011000111000111000111) × 2^(-63)
可见p有63bit之多,可是只有52bit可以保存,所以只能取52bit。
于是就只有(+1) × (1.0011010001100101001100010101111101101011010110001110) × 2^(-63)(+1) × (1.0011010001100101001100010101111101101011010110001111) × 2^(-63)可共选择。当然是哪一个最接近取哪一个,所以取的是第一个(如果这两个同样接近,取末尾为0的那个)。其实这个值是11111111111111110656,而chrome知道后面几个数不准确所以取了 0,因为在表示成小数的时候,后面的的 0 是会被自动忽略的,可是这里不是表示成小数。

几个有趣的数字。。。

var a = 9007199254740992; // var a = 2^53
a - 1 // 9007199254740991,2^53-1 此值有16位十进制有效数字,其他的只有 15 位
a + 1 // 9007199254740992
a + 2 // 9007199254740994
a + 3 // 9007199254740996
a + 4 // 9007199254740996

http://babbage.cs.qc.cuny.edu...

JavaScript能表示并进行精确算术运算的整数范围为:正负2的53次方,也即从最小值-9007199254740992到最大值+9007199254740992之间的范围;对于超过这个范围的整数,JavaScript依旧可以进行运算,但却不保证运算结果的精度。

或许你可以参考下这个

推荐问题
宣传栏