一个数字在不损失精度的情况下可以达到的 JavaScript 的最高整数值是多少?

IT技术 javascript math browser cross-browser
2020-12-18 23:59:35

这是由语言定义的吗?有定义的最大值吗?在不同的浏览器中是不同的吗?

6个回答

JavaScript 有两种数字类型:NumberBigInt

最常用的数字类型Number是 64 位浮点IEEE 754数字。

这种类型的最大精确整数值为Number.MAX_SAFE_INTEGER,即:

  • 2 53 -1,或
  • +/- 9,007,199,254,740,991,或
  • 九亿七万亿一千九百九十二亿五千四百万七十万九千九十一

从这个角度来看:一千万亿字节是 PB(或一千 TB)。

在此上下文中,“安全”是指准确表示整数并正确比较它们的能力。

从规范:

请注意,所有大小不大于 2 53的正整数和负整数都可以在Number类型中表示(实际上,整数 0 有两种表示形式,+0 和 -0)。

要安全地使用大于此值的整数,您需要使用BigInt,它没有上限。

请注意,按位运算符和移位运算符对 32 位整数进行运算,因此在这种情况下,最大安全整数为 2 31 -1 或 2,147,483,647。

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 进行编码是不明确的。

这似乎是正确的,但是有没有什么地方定义了它,如 C 的 MAX_INT 或 Java 的 Integer.MAX_VALUE?
2021-02-10 23:59:35
那么我们可以用来确保精确精度的最小和最大整数是多少?
2021-02-10 23:59:35
4294967295 === Math.pow(2,32) - 1;
2021-02-17 23:59:35
也许值得注意的是,javascript 中没有实际的 (int)。Number 的每个实例都是 (float) 或 NaN。
2021-02-26 23:59:35
9007199254740992 并不是真正的最大值,这里的最后一位已经假定为零,因此您失去了 1 位精度。真正的安全号码是 9007199254740991 ( Number.MAX_SAFE_INTEGER )
2021-03-02 23:59:35

>= ES6:

Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;

<= ES5

参考

Number.MAX_VALUE;
Number.MIN_VALUE;

我已经编辑了这个问题,使其更精确地想要最大 Integer 值,而不仅仅是最大 Number 值。很抱歉在这里造成混乱。
2021-02-07 23:59:35
请注意,这Number.MIN_VALUE是可能的最小数。至少值(即小于其他东西)是可能-Number.MAX_VALUE
2021-02-16 23:59:35
这是最大的浮点值。问题是关于最高整数值。而 whileNumber.MAX_VALUE是一个整数,你不能在2^53不失去精度的情况下过去
2021-02-19 23:59:35
返回的结果是否保证在所有浏览器上都相同?
2021-02-20 23:59:35
ES6 引入Number.MIN_SAFE_INTEGERNumber.MAX_SAFE_INTEGER
2021-02-28 23:59:35

它是 2 53 == 9 007 199 254 740 992。这是因为Numbers 以浮点形式存储在 52 位尾数中。

最小值为 -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

@TedBigham:oop,准备得太快了。谢谢你纠正我两次。
2021-02-09 23:59:35
见吉米的论据9,007,199,254,740,991,而不是9,007,199,254,740,992这里结合我的后续行动,这似乎很有说服力。
2021-02-23 23:59:35
尽管在合理的时间范围内永远不会到达 for 循环的结尾,但您可能希望说 i += 1000000000
2021-03-01 23:59:35
@ninjagecko,他从 MAX_INT 开始,所以结束就在那里。同样使用 i+= 1000000000 将使其不再是无限循环。尝试一下。
2021-03-04 23:59:35

在 JavaScript 中,有一个数字叫做Infinity

例子:

(Infinity>100)
=> true

// Also worth noting
Infinity - 1 == Infinity
=> true

Math.pow(2,1024) === Infinity
=> true

对于有关此主题的某些问题,这可能就足够了。

有些东西告诉我无穷大不符合整数的条件。:)
2021-02-07 23:59:35
也 (Infinity<100) => false 和 Math.pow(2,1024) === Infinity
2021-02-20 23:59:35
注意 Infinity - 1 === Infinity
2021-02-28 23:59:35
同样值得一提的是,它也可以处理负无穷大。所以1 - Infinity === -Infinity
2021-03-07 23:59:35
但是min当你在寻找一个最小值时初始化一个变量就足够了
2021-03-08 23:59:35

吉米的回答正确代表连续的JavaScript整数频谱-90071992547409929007199254740992包容性(对不起9007199254740993,你可能会认为你是9007199254740993,但你错了! 下面或示范的jsfiddle)。

console.log(9007199254740993);

但是,没有以编程方式找到/证明这一点的答案(除了 CoolAJ86 在他的答案中提到的将在 28.56 年内完成的答案;),所以这里有一种稍微更有效的方法来做到这一点(准确地说,它更有效)大约 28.55999999968312 年 :),以及测试小提琴

/**
 * 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);

@MickLH:在增量发生之前评估x++会为您提供 x 的值,因此这可能解释了差异。如果您希望表达式的计算结果与 x 的最终值相同,则应将其更改为++x
2021-02-18 23:59:35
var x=Math.pow(2,53)-3;while (x!=x+1) x++; -> 9007199254740991
2021-02-21 23:59:35
你用你自己的代码得到 9007199254740992,我没有使用 x 的最终值,而是出于偏执的原因对 x++ 的最终评估。谷歌浏览器顺便说一句。
2021-02-27 23:59:35
@MickLH:我用那个代码得到 9007199254740992 您使用什么 JavaScript 引擎进行测试?
2021-03-01 23:59:35
@CoolAJ86:大声笑,我期待着 2040 年 3 月 15 日。如果我们的数字匹配,我们应该举办一个派对:)
2021-03-02 23:59:35