如何检查一个数是否等于无穷大?

115

我有一系列Javascript计算,根据用户选择会在IE中显示Infinity。

如何阻止出现单词Infinity,而是显示0.0

8个回答

204
if (result == Number.POSITIVE_INFINITY || result == Number.NEGATIVE_INFINITY)
{
    // ...
}
你可以根据需要处理 "NaN",并可能使用isFinite函数。如果你的数字是POSITIVE_INFINITYNEGATIVE_INFINITYNaN,则isFinite返回false
if (isFinite(result))
{
    // ...
}

4
为什么要使用 Number.(POSITIVE|NEGATIVE)_INFINITY 而不是 -?Infinity 或者 -?1/0 - Eli Grey
5
@Eli: 全局的Infinity属性不是只读的,这意味着它可以被重新定义:例如,var x = 42; Infinity = 42; alert(x === Infinity);将显示“true”。(尽管这是一个晦涩的情况,但任何决定重新定义InfinityNaN等的人都应该预料到会发生奇怪的事情。) - LukeH
2
忽略 Number.(POSITIVE|NEGATIVE)_INFINITY 不是只读的事实,Infinity 在严格模式下确实是只读的。另外,关于我向你演示的 -?1/0 情况呢?总之,几乎总是应该使用 isFinite - Eli Grey
1
@Eli:在我的测试中,Number.POSITIVE_INFINITYNumber.NEGATIVE_INFINITY是只读的(在Chrome8、FF3.6和IE8上测试过)。使用1/0可以正常工作,但对于代码维护者来说,你实际上想要测试什么可能不太明显。我同意使用isFinite几乎总是更好的方法——这就是为什么我在我的答案中提到它的原因——但只有OP可以决定它是否符合他们的要求。 - LukeH
5
它们不是只读的(即 不可配置),它们只是具有getter但没有setter的访问器。您可以使用Object.defineProperty__defineGetter__重新定义它们。另一方面,在严格模式下,Infinity是不可配置的。 - Eli Grey
显示剩余2条评论

17

ES6中,Number.isFinite()方法用于确定传递的值是否为有限数字。

Number.isFinite(Infinity);  // false
Number.isFinite(NaN);       // false
Number.isFinite(-Infinity); // false

Number.isFinite(0);         // true
Number.isFinite(2e64);      // true

自ECMAScript 1起就可以访问。 - MohaMad

10

一个简单的 n === n+1n === n/0 即可:

function isInfinite(n) {
  return n === n/0;
}

请注意,本地的isFinite()会将输入强制转换为数字。例如,isFinite([])isFinite(null)都是true


1
这个答案是完全错误的。对于所有大于2^53,即1e30的数字,n === n+1都会评估为true。除法hack也适用于NaN和-Infinity。然而,LukeH的答案提供了更易读的代码。 - tglas
@tglas 为什么加号是那样的?很高兴除法是稳定的。在我看来,我的代码更易读、更具包容性,因为数学比语言更普遍。 - ryanve
1
因为 IEEE 64位浮点数具有53个有效的二进制数字(参见https://en.wikipedia.org/wiki/IEEE_754),所以 n + 1 无法表示并且可能会受到舍入的影响。 好吧,即使整数也会受到舍入误差的影响。 另外,我不认为你的代码是“数学证明”,可以尝试 n === n/-0。 当使用 +/-inf 完成实数时,除非假定底层零序列为正数,否则您的极限没有定义良好。 - tglas
谢谢 @tglas 我会一直喜欢 JavaScript 可以除以零 :) - ryanve

5

进行普通比较:

(number === Infinity || number === -Infinity)

或者为了节省几个字符:
Math.abs(number) === Infinity

为什么要使用它

  1. !(Number.isFinite(number)) 对于 NaN 输入会出错。
  2. Number.POSITIVE_INFINITYNumber.NEGATIVE_INFINITY 可以重新定义;它们是可配置的
  3. Infinity-Infinity严格模式 下是只读的。
  4. 这是最短的解决方案。

2

实际上,n === n + 1 对于大于 51 位的数字也是有效的,例如:

1e16 + 1 === 1e16; // true
1e16 === Infinity; // false

4
这应该是对Ryanve答案的评论。 - Gary
“work” 是具有误导性的。请说“也会评估为 true”。 - Константин Ван

0

我喜欢使用Lodash,因为它具有多种防御性编码的原因以及可读性。ES6 Number.isFinite非常好,不会出现非数字值的问题,但如果无法使用ES6,您已经拥有了Lodash,或者想要更简洁的代码:_.isFinite

_.isFinite(Infinity); // false
_.isFinite(NaN); // false
_.isFinite(-Infinity); // false

_.isFinite(null); // false
_.isFinite(3); // true
_.isFinite('3'); // true

-1
我遇到了一个场景,需要检查值是否为 NaNInfinity 类型,但要将字符串作为有效结果传递。因为许多文本字符串将产生误报的 NaN,所以我制定了一个简单的解决方案来规避这个问题:
  const testInput = input => input + "" === "NaN" || input + "" === "Infinity";

上述代码将值转换为字符串,并检查它们是否严格等于NaN或Infinity(您需要添加另一个负无穷大的情况)。

因此:

testInput(1/0); // true
testInput(parseInt("String")); // true
testInput("String"); // false

这篇文章并没有真正回答实际问题,作为已被接受的答案下面的评论会更好。原帖是关于数字和无限大的,而不是字符串和NaN等内容。 - code_dredd
你可能是对的,@code_dredd - 这个轶事并不相关。但解决方案仍然有效:它可以检测到无穷大的数字 - 如果我错了,请纠正我。 - dmitrizzle
那不是重点。已经有一个回答展示了如何去正确地实现这个。你所做的“可以工作”只是因为语言本身做了愚蠢的事情,并且在处理类型时不一致。请不要写出像这样的hack代码,节省你自己的时间。 - code_dredd
如果我使用 toString() 会让你更开心吗?请随意点踩或说明原因,说明这可能会产生不一致的结果或为什么不推荐使用该方法。到目前为止,我仍然认为它为寻找答案的人提供了一个选项,并且没有任何具体的原因说明这是危险的、不稳定的等等。 - dmitrizzle

-2

在编程中,你可以使用 window 下的 isFinite 方法,例如:isFinite(123)

你也可以自己编写一个函数,如下所示:

function isInfinite(num) {
 return !isFinite(num);
}

并使用如下:

isInfinite(null); //false
isInfinite(1); //false
isInfinite(0); //false
isInfinite(0.00); //false
isInfinite(NaN); //true
isInfinite(-1.797693134862316E+308); //true
isInfinite(Infinity); //true
isInfinite(-Infinity); //true
isInfinite(+Infinity); //true
isInfinite(undefined); //true

你也可以使用 Number.isFinite,它还会检查值是否为数字,并且对于检查 undefinednull 等更准确。

或者你可以像这样进行 polyfill

Number.isFinite = Number.isFinite || function(value) {
  return typeof value === 'number' && isFinite(value);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接