这是由语言定义的吗?有确定的最大值吗?在不同的浏览器中是否有所不同?
当前回答
Try:
maxInt = -1 >>> 1
在Firefox 3.6中是2^31 - 1。
其他回答
简短的回答是“视情况而定。”
如果你在任何地方使用位操作符(或者如果你引用数组的长度),范围是:
无符号:0…(1 > > > 0)
签名:(-(1 > > > 1)1)……(1 > > > 1)
(恰巧按位操作符和数组的最大长度被限制为32位整数。)
如果你不使用位操作符或使用数组长度:
签名:(-Math pow (2.53)) ... + Math . pow (2.53))
这些限制是由“Number”类型的内部表示施加的,通常对应于IEEE 754双精度浮点表示。(请注意,与典型的有符号整数不同,由于内部表示的特征,负极限的大小与正极限的大小相同,它实际上包括一个负0!)
要用于位操作的任何值必须在0x80000000(-2147483648或-2^31)和0x7fffffff(2147483647或2^31 - 1)之间。
控制台会告诉您0x80000000等于+2147483648,但是0x80000000 & 0x80000000等于-2147483648。
许多先前的答案显示9007199254740992 === 9007199254740992 + 1为真,以验证9,007,199,254,740,991是最大且安全的整数。
但如果我们继续积累:
input: 9007199254740992 + 1 output: 9007199254740992 // expected: 9007199254740993
input: 9007199254740992 + 2 output: 9007199254740994 // expected: 9007199254740994
input: 9007199254740992 + 3 output: 9007199254740996 // expected: 9007199254740995
input: 9007199254740992 + 4 output: 9007199254740996 // expected: 9007199254740996
我们可以看到,在大于9,007,199,254,740,992的数字中,只有偶数是可表示的。
这是一个解释双精度64位二进制格式如何工作的条目。让我们看看如何使用这种二进制格式保存(表示)9,007,199,254,740,992。
使用一个简短的版本从4,503,599,627,370,496演示:
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
|-- 52 bits --| |exponent part| |-- 52 bits --|
在箭头的左边,我们有位值1和一个相邻的基数点。通过消耗左边的指数部分,基数点向右移动52步。基数点在最后,我们得到纯二进制的4503599627370496。
现在,让我们继续将分数部分加1,直到所有的位都设置为1,这等于十进制的9,007,199,254,740,991。
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
(+1)
1 . 0000 ---- 0001 * 2^52 => 1 0000 ---- 0001.
(+1)
1 . 0000 ---- 0010 * 2^52 => 1 0000 ---- 0010.
(+1)
.
.
.
1 . 1111 ---- 1111 * 2^52 => 1 1111 ---- 1111.
因为64位双精度格式严格地为分数部分分配了52位,如果我们添加另一个1,就没有更多的位可用了,所以我们可以做的是将所有位设置为0,并操作指数部分:
┏━━▶ This bit is implicit and persistent.
┃
1 . 1111 ---- 1111 * 2^52 => 1 1111 ---- 1111.
|-- 52 bits --| |-- 52 bits --|
(+1)
1 . 0000 ---- 0000 * 2^52 * 2 => 1 0000 ---- 0000. * 2
|-- 52 bits --| |-- 52 bits --|
(By consuming the 2^52, radix
point has no way to go, but
there is still one 2 left in
exponent part)
=> 1 . 0000 ---- 0000 * 2^53
|-- 52 bits --|
现在我们得到9,007,199,254,740,992,对于比它更大的数,格式只能处理2的增量,因为分数部分的每一个增量1最终都会在指数部分乘以左边的2。这就是为什么双精度64位二进制格式不能保存大于9,007,199,254,740,992的奇数:
(consume 2^52 to move radix point to the end)
1 . 0000 ---- 0001 * 2^53 => 1 0000 ---- 0001. * 2
|-- 52 bits --| |-- 52 bits --|
按照这种模式,当数字大于9,007,199,254,740,992 * 2 = 18,014,398,509,481,984时,只能保持4倍的分数:
input: 18014398509481984 + 1 output: 18014398509481984 // expected: 18014398509481985
input: 18014398509481984 + 2 output: 18014398509481984 // expected: 18014398509481986
input: 18014398509481984 + 3 output: 18014398509481984 // expected: 18014398509481987
input: 18014398509481984 + 4 output: 18014398509481988 // expected: 18014398509481988
那么[2 251 799 813 685 248,4 503 599 627 370 496)之间的号码呢?
1 . 0000 ---- 0001 * 2^51 => 1 0000 ---- 000.1
|-- 52 bits --| |-- 52 bits --|
0.1的二进制值正好是2^-1 (=1/2)(=0.5) 因此,当数字小于4,503,599,627,370,496(2^52)时,有一位可用来表示整数的1/2倍:
input: 4503599627370495.5 output: 4503599627370495.5
input: 4503599627370495.75 output: 4503599627370495.5
小于2,251,799,813,685,248 (2^51)
input: 2251799813685246.75 output: 2251799813685246.8 // expected: 2251799813685246.75
input: 2251799813685246.25 output: 2251799813685246.2 // expected: 2251799813685246.25
input: 2251799813685246.5 output: 2251799813685246.5
/**
Please note that if you try this yourself and, say, log
these numbers to the console, they will get rounded. JavaScript
rounds if the number of digits exceed 17. The value
is internally held correctly:
*/
input: 2251799813685246.25.toString(2)
output: "111111111111111111111111111111111111111111111111110.01"
input: 2251799813685246.75.toString(2)
output: "111111111111111111111111111111111111111111111111110.11"
input: 2251799813685246.78.toString(2)
output: "111111111111111111111111111111111111111111111111110.11"
指数部分的取值范围是多少?格式为它分配了11位。
来自维基百科(欲了解更多细节,请访问那里)
为了使指数部分等于2^52,我们需要令e = 1075。
火狐3似乎不存在庞大数字的问题。
1e+200 * 1e+100将计算到1e+300。
Safari似乎也没有问题。(顺便说一句,如果有人想测试的话,这是在Mac上进行的。)
除非我脑子进水了,否则这比64位整数大得多。
其他人可能已经给出了一般的答案,但我认为给出一个快速确定它的方法会是一个好主意:
for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);
这给了我9007199254740992在Chrome 30不到一毫秒。
它将测试2的幂,以找出当“加”1时,哪一个等于他自己。
推荐文章
- 在数组中获取所有选中的复选框
- 如何为Firebase构建云函数,以便从多个文件部署多个函数?
- 如何发送推送通知到web浏览器?
- AngularJS:工厂和服务?
- js:将一个组件包装成另一个组件
- 父ng-repeat从子ng-repeat的访问索引
- JSHint和jQuery: '$'没有定义
- 模仿JavaScript中的集合?
- 用JavaScript验证电话号码
- 如何在HTML5中改变视频的播放速度?
- 谷歌地图API v3:我可以setZoom后fitBounds?
- 用jQuery检查Internet连接是否存在?
- ES6/2015中的null安全属性访问(和条件赋值)
- 与push()相反;
- JS字符串“+”vs concat方法