这是由语言定义的吗?有确定的最大值吗?在不同的浏览器中是否有所不同?
当前回答
Node.js和谷歌Chrome似乎都使用1024位浮点值,因此:
Number.MAX_VALUE = 1.7976931348623157e+308
其他回答
的wrotes:
任何你想用于位操作的东西都必须在 0x80000000(-2147483648或-2^31)和0x7fffffff(2147483647或2^31 - 1)。 控制台会告诉您0x80000000等于+2147483648,但是 0x80000000 & 0x80000000 = -2147483648
十六进制小数是无符号的正数值,因此0x80000000 = 2147483648 -这在数学上是正确的。如果你想让它成为一个带符号的值,你必须右移:0x80000000 >> 0 = -2147483648。你也可以写成1 << 31。
我这样写:
var max_int = 0x20000000000000;
var min_int = -0x20000000000000;
(max_int + 1) === 0x20000000000000; //true
(max_int - 1) < 0x20000000000000; //true
int32也是一样
var max_int32 = 0x80000000;
var min_int32 = -0x80000000;
让我们来看看源头
描述
The MAX_SAFE_INTEGER constant has a value of 9007199254740991 (9,007,199,254,740,991 or ~9 quadrillion). The reasoning behind that number is that JavaScript uses double-precision floating-point format numbers as specified in IEEE 754 and can only safely represent numbers between -(2^53 - 1) and 2^53 - 1. Safe in this context refers to the ability to represent integers exactly and to correctly compare them. For example, Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 will evaluate to true, which is mathematically incorrect. See Number.isSafeInteger() for more information. Because MAX_SAFE_INTEGER is a static property of Number, you always use it as Number.MAX_SAFE_INTEGER, rather than as a property of a Number object you created.
浏览器兼容性
许多先前的答案显示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位整数大得多。
推荐文章
- 什么时候JavaScript是同步的?
- 为什么Python的无穷散列中有π的数字?
- 如何在Typescript中解析JSON字符串
- Javascript reduce()在对象
- 在angularJS中& vs @和=的区别是什么
- 错误"Uncaught SyntaxError:意外的标记与JSON.parse"
- JavaScript中的querySelector和querySelectorAll vs getElementsByClassName和getElementById
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?
- setTimeout带引号和不带括号的区别
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 用javascript检查输入字符串中是否包含数字
- 如何使用JavaScript分割逗号分隔字符串?
- 在Javascript中~~(“双波浪号”)做什么?
- 谷歌chrome扩展::console.log()从后台页面?