var a = 11111111111111111111;
console.log(a);
//chrome : 11111111111111110000
//nodejs : 11111111111111110000
求大神解释,为什么会打印出不相符的结果?
var a = 11111111111111111111;
console.log(a);
//chrome : 11111111111111110000
//nodejs : 11111111111111110000
求大神解释,为什么会打印出不相符的结果?
浮点数范围:
±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分解为上述形式在二进制数的运算里更方便。
现在我们用二进制的数来表示 m
,m
被化为二进制数之后最高为肯定为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
JavaScript能表示并进行精确算术运算的整数范围为:正负2的53次方,也即从最小值-9007199254740992到最大值+9007199254740992之间的范围;对于超过这个范围的整数,JavaScript依旧可以进行运算,但却不保证运算结果的精度。
8 回答4.6k 阅读✓ 已解决
6 回答3.3k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
5 回答6.3k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
4 回答2.7k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
这个跟计算机中用于存储数字的方法有关. 你想想, 你这个整数都已经那么大啦, 忽略了那几百大小, 又有什么影响呢? 至于这是像IEEE754不能存储0.3那样的原因, 还是为了节省开销, 我也不清楚. 不过我们可以来做一个有趣的实验.
在控制台输入Number.MAX_VALUE, 打印出的数字是1.7976931348623157e+308, 注意数他的有效数字位数, 是17. 你试着打印179769313486231571, 最后添加的1也会变成0, 输入1234567890123456789, 会输出1234567890123456800, 可见17是他能达到的最大位数, 再大就会被置为0. 再看你的a, 是16位, 为什么呢? 可能是因为单身狗比较特殊.