扫码关注官方订阅号
var a = 11111111111111111111; console.log(a); //chrome : 11111111111111110000 //nodejs : 11111111111111110000
求大神解释,为什么会打印出不相符的结果?
走同样的路,发现不同的人生
这个跟计算机中用于存储数字的方法有关. 你想想, 你这个整数都已经那么大啦, 忽略了那几百大小, 又有什么影响呢? 至于这是像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 = s* m *2^e
s
m
e
其实,把f分解为上述形式在二进制数的运算里更方便。现在我们用二进制的数来表示 m,m被化为二进制数之后最高为肯定为1(二进制数只有0 1 而最高位的0 我们通常不写)。通过移动小数点,我们可以把 m 写为1+p 其中 p 是小于 1 的非负数。由于最高位固定为 1 所以可以用 52bit 表示 p。也就是我们其实用 53bit 表示了 m,虽然 m 只占用了 52bit。所以对于(正则)浮点数,IEEE 745 只能保存 53 个有效bit,
1+p
比如个 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 是会被自动忽略的,可是这里不是表示成小数。
(1001101000110010100110001010111110110101101011000111000111000111)
(+1) × (1.001101000110010100110001010111110110101101011000111000111000111) × 2^(-63)
p
(+1) × (1.0011010001100101001100010101111101101011010110001110) × 2^(-63)
(+1) × (1.0011010001100101001100010101111101101011010110001111) × 2^(-63)
11111111111111110656
几个有趣的数字。。。
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依旧可以进行运算,但却不保证运算结果的精度。
或许你可以参考下这个
嘿嘿,点这里一峰es6安全整数 可以参考一下
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
这个跟计算机中用于存储数字的方法有关. 你想想, 你这个整数都已经那么大啦, 忽略了那几百大小, 又有什么影响呢? 至于这是像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是因为最大位数的原因导致的.
刚才试了几个比较特殊的,比如:
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 是会被自动忽略的,可是这里不是表示成小数。几个有趣的数字。。。
http://babbage.cs.qc.cuny.edu...
JavaScript能表示并进行精确算术运算的整数范围为:正负2的53次方,也即从最小值-9007199254740992到最大值+9007199254740992之间的范围;对于超过这个范围的整数,JavaScript依旧可以进行运算,但却不保证运算结果的精度。
或许你可以参考下这个
嘿嘿,点这里一峰es6安全整数 可以参考一下