这是由语言定义的吗?有定义的最大值吗?在不同的浏览器中是否不同?
这是由语言定义的吗?有定义的最大值吗?在不同的浏览器中是否不同?
Number
和BigInt
。Number
是64位浮点数IEEE 754数。该类型的最大精确整数值是Number.MAX_SAFE_INTEGER
,它是:
要安全地使用比此更大的整数,您需要使用没有上界的请注意,所有正的和负的整数,其大小不超过 2^53,都可以用
Number
类型表示(确实,整数 0 有两个表示,+0 和 -0)。
BigInt
。const log = console.log
var x = 9007199254740992
var y = -x
log(x == x + 1) // true !
log(y == y - 1) // also true !
// Arithmetic operators work, but bitwise/shifts only operate on int32:
log(x / 2) // 4503599627370496
log(x >> 1) // 0
log(x | 1) // 1
关于数字9,007,199,254,740,992的技术说明:存在该值的精确IEEE-754表示,你可以将该值赋给变量并从中读取,因此对于在不大于该值的整数领域中非常小心地选择应用程序,你可以将其视为最大值。
在一般情况下,必须将这个IEEE-754值视为不精确的,因为它是模棱两可的,无法确定它是否编码了逻辑值9,007,199,254,740,992或9,007,199,254,740,993。
4294967295 === Math.pow(2,32) - 1;
- coolaj86>= ES6:
Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;
<= ES5
参考此处:
Number.MAX_VALUE;
Number.MIN_VALUE;
console.log('MIN_VALUE', Number.MIN_VALUE);
console.log('MAX_VALUE', Number.MAX_VALUE);
console.log('MIN_SAFE_INTEGER', Number.MIN_SAFE_INTEGER); //ES6
console.log('MAX_SAFE_INTEGER', Number.MAX_SAFE_INTEGER); //ES6
Number.MIN_VALUE
是最小的可能的_正数_。最小的值(即小于任何其他值的值)可能是-Number.MAX_VALUE
。 - Michael ScheperNumber.MIN_SAFE_INTEGER
和 Number.MAX_SAFE_INTEGER
。 - superlukas这是因为Number
存储为52位尾数的浮点数,因此它等于2的53次方,即9,007,199,254,740,992。
最小值为-2的53次方。
这导致了一些有趣的事情发生。
Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true
这也可能很危险哦 :)
var MAX_INT = Math.pow(2, 53); // 9 007 199 254 740 992
for (var i = MAX_INT; i < MAX_INT + 2; ++i) {
// infinite loop
}
更多阅读:http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html
i += 1000000000
。 - ninjagecko在JavaScript中,有一个称为Infinity
的数字。
例如:
(Infinity>100)
=> true
// Also worth noting
Infinity - 1 == Infinity
=> true
Math.pow(2,1024) === Infinity
=> true
对于某些关于这个主题的问题,这可能已经足够了。
1 - Infinity === -Infinity
。 - dmccabe9007199254740992 === 9007199254740992 + 1
是true,以验证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
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
|-- 52 bits --| |exponent part| |-- 52 bits --|
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 --|
(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时,只能保留四分之一的小数:
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 --|
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。
Jimmy的回答正确地表示了JavaScript整数连续谱,范围为-9007199254740992至9007199254740992(抱歉,9007199254740993,你可能认为自己是9007199254740993,但你错了!下面或在jsfiddle中演示)。
console.log(9007199254740993);
然而,没有一个程序能够找到/证明这一点(除了CoolAJ86在他的答案中提到的需要28.56年才能完成的方法 ;),因此这里有一种稍微更有效的方法来实现这个目标(准确地说,它比原来的方法快了约28.559999999968312年 :),同时还附带了一个测试代码片段:
/**
* Checks if adding/subtracting one to/from a number yields the correct result.
*
* @param number The number to test
* @return true if you can add/subtract 1, false otherwise.
*/
var canAddSubtractOneFromNumber = function(number) {
var numMinusOne = number - 1;
var numPlusOne = number + 1;
return ((number - numMinusOne) === 1) && ((number - numPlusOne) === -1);
}
//Find the highest number
var highestNumber = 3; //Start with an integer 1 or higher
//Get a number higher than the valid integer range
while (canAddSubtractOneFromNumber(highestNumber)) {
highestNumber *= 2;
}
//Find the lowest number you can't add/subtract 1 from
var numToSubtract = highestNumber / 4;
while (numToSubtract >= 1) {
while (!canAddSubtractOneFromNumber(highestNumber - numToSubtract)) {
highestNumber = highestNumber - numToSubtract;
}
numToSubtract /= 2;
}
//And there was much rejoicing. Yay.
console.log('HighestNumber = ' + highestNumber);
var MAX_INT = 4294967295;
我以为我会聪明一些,用更实用的方法找到使得 x + 1 === x
的值。
我的机器每秒只能计算1000万次左右……所以我将在28.56年后发布最终答案。
如果你等不了那么久,我敢打赌:
9007199254740992 === Math.pow(2, 53) + 1
就已经足够证明了4294967295
,它是 Math.pow(2,32) - 1
,以避免位移时出现预期外的问题查找 x + 1 === x
:
(function () {
"use strict";
var x = 0
, start = new Date().valueOf()
;
while (x + 1 != x) {
if (!(x % 10000000)) {
console.log(x);
}
x += 1
}
console.log(x, new Date().valueOf() - start);
}());
简短的回答是“这要看情况”。
如果你在使用位运算符(或者是在引用数组的长度),范围如下:
无符号数:0…(-1>>>0)
有符号数:(-(-1>>>1)-1)…(-1>>>1)
(正好位运算符和数组的最大长度都限制在32位整数内。)
如果你没有使用位运算符或者处理数组长度:
有符号数:(-Math.pow(2,53))…(+Math.pow(2,53))
这些限制是由“Number”类型的内部表示所强加的,通常对应于IEEE 754双精度浮点表示。(请注意,与典型的有符号整数不同的是,负极限的大小与正极限的大小相同,这是由内部表示的特性决定的,它实际上包括一个负零!)
ECMAScript 6:
Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;
MAX_SAFE_INTEGER
在所有浏览器中是否可靠?应该前向计算还是逆推计算?即,Number.MAX_SAFE_INTEGER = 2 * (Math.pow(2, 52) - 1) + 1;
可以翻译为:在所有浏览器中,通过逆向计算来确定 MAX_SAFE_INTEGER
是否可靠?是否应该使用正向计算方法?例如:Number.MAX_SAFE_INTEGER = 2 * (Math.pow(2, 52) - 1) + 1;
- kjvMath.pow(2, 53)-1
这个操作安全吗?它会比最大的安全整数还要大一。 - ioquatixMath.pow(2, 53)
可以准确表示,并且减法运算也是明确定义和精确的。 - Daira Hopwood其他人可能已经给出了通用的答案,但我认为提供一种快速确定它的方法是一个好主意:
for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);
在 Chrome 30 中,这个方法能够在不到一毫秒的时间内得出 9007199254740992。
该方法会测试 2 的幂次方,找到其中一个数,使得在加上 1 后等于自身。
1n << 10000n
是一个非常非常大的整数,不会失去任何精度,也不需要任何依赖项(不用说,远远没有达到极限)。 - Amadann
。BigInt
类是ES2020规范草案的一部分,已经在大多数浏览器中实现; 您可以尝试在Chrome或Firefox中评估它,而无需使用外部库,并获得3011位数字的BigInt
。 - Amadan