js`Number`类型会加起来等于Infinity吗?

时间:2018-10-13 04:08:15

标签: javascript floating-point

如果有足够的时间,此循环会结束吗?

for (let i = 0; 1 / i > 0; i++) {} // js code [0]

我想i到达Number.POSITIVE_INFINITY时会这样,但是不知道如何测试。

修改

for (let i = 0; 1 / i > 0; i += k) {} // js code [1]
  1. 使 js代码[1] 完成的最小正数k是多少? (至少k = 1e304会)

  2. 让我们假设问题1的答案为K,大于K的数字是否可以保证 js代码[1] 的完成?

2 个答案:

答案 0 :(得分:6)

不,它永远不会结束,因为在高数字下,数字精度会失败。例如,将1添加到1e16会得到一个数字,该数字也等于1e16-超过某一点,它将永远不会进行:

console.log((1e16 + 1) === 1e16);

这是9007199254740992。 JavaScript的MAX_SAFE_INTEGER9007199254740991。将一个加到9007199254740991会得到9007199254740992,但是将一个加到9007199254740992会得到相同的数字9007199254740992

console.log(9007199254740991 + 1 === 9007199254740992);
console.log(9007199254740992 + 1 === 9007199254740992);

您在Infinity附近到达1.7e308

答案 1 :(得分:2)

k完成的最小正数for (let i = 0; 1 / i > 0; i += k) {}是2 970 +2 918 ,它是9979201547673601274109728689479476941425536662556495940151194794704206738934049246746743498432906272845051601607544504207607607407697406946786576546946546715476546946546946546946546946546576546946546546546546546546546546546546546546546546546546546786546546716576545474576546546546546546546546546546546546546546546546576576546546546546546546546546546546546546546572亿英镑

JavaScript是ECMAScript的方言,它指定它使用64位(二进制)IEEE-754浮点格式,并具有从最近到最近的关系。在这种格式中,最大的有限数在从2 1023 (包括)到2 1024 (不包括)的binade中。由于浮点数的有效位(分数部分)具有53位,因此这些数的最低有效位的位置值为2 1023-52 = 2 971 。这称为最低精度单位(ULP)。 (ULP是浮点数指数的函数;它随该数字成比例缩放。)

计算i+k时,结果将四舍五入到最接近的可表示数字。如果k小于i的½ULP,则最接近i + k的数学值的可表示数为i,因此不会发生变化当执行i = i+k时。如果k恰好是i的½ULP,则i + k的数学值恰好在i与下一个可表示的值之间。根据四舍五入原则,如果i的低位为零,则四舍五入;如果为k,低位为四舍五入。因此,如果i = i+k恰好是最大有限浮点数的½ULP,则k不会对其中的一半产生任何变化,因此循环不会继续进行。

如果i超过i的½ULP,则k + i的数学值比{{1 }},结果是i加一个ULP,所以循环继续进行。 (在特殊情况下,i是可表示的最大有限值,加法将产生无穷大,由于1 / i将为零,因此该循环将终止循环。)

如上所述,最大值的ULP为2 971 。 ½ULP是2 970 。我们需要k使其比此值大尽可能小,因此我们想为其添加一个ULP。 (一个最大规模的ULP,而不是最大数量的ULP。)2 970 的ULP是2 970-52 = 2 918

因此,导致循环终止的最小正数k是2 970 +2 918