【问题标题】:How do I check if a number evaluates to infinity?如何检查一个数字是否为无穷大?
【发布时间】:2011-06-11 02:33:58
【问题描述】:

我有一系列 Javascript 计算(仅在 IE 下)根据用户选择显示 Infinity。

如何阻止出现Infinity这个词,例如,改为显示0.0

【问题讨论】:

    标签: javascript infinity


    【解决方案1】:
    if (result == Number.POSITIVE_INFINITY || result == Number.NEGATIVE_INFINITY)
    {
        // ...
    }
    

    您可以改用isFinite 函数,具体取决于您要如何对待NaN。如果您的号码是 POSITIVE_INFINITYNEGATIVE_INFINITYNaNisFinite 将返回 false

    if (isFinite(result))
    {
        // ...
    }
    

    【讨论】:

    • 为什么使用Number.(POSITIVE|NEGATIVE)_INFINITY 而不是-?Infinity-?1/0
    • @Eli:全局 Infinity 属性不是只读的,这意味着它可以重新定义:例如,var x = 42; Infinity = 42; alert(x === Infinity); 显示 "true"。 (诚​​然,这是一个不起眼的案例,任何决定重新定义 InfinityNaN 等的人都应该预料到会发生奇怪的事情。)
    • 忽略Number.(POSITIVE|NEGATIVE)_INFINITY 也不是只读的事实,Infinity 在严格模式下是只读的。另外,我向您介绍的-?1/0 案例呢?无论如何,您几乎应该总是使用isFinite
    • @Eli:在我的测试中,Number.POSITIVE_INFINITYNumber.NEGATIVE_INFINITY 只读的(在 Chrome8、FF3.6 和 IE8 上测试)。使用1/0 可以正常工作,但对于您的代码维护者来说,您实际尝试测试的内容并不那么明显。我同意使用 isFinite 几乎总是更好的做事方式——这就是我在回答中提到它的原因——但只有 OP 可以决定它是否符合他们的要求。
    • 它们不是只读的(阅读:non-configurable),它们只是具有 getter 而没有 setter 的访问器。您可以使用Object.defineProperty__defineGetter__ 重新定义它们。 Infinity,另一方面,在严格模式下不可配置的。
    【解决方案2】:

    ES6中,Number.isFinite()方法判断传入的值是否为有限数。

    Number.isFinite(Infinity);  // false
    Number.isFinite(NaN);       // false
    Number.isFinite(-Infinity); // false
    
    Number.isFinite(0);         // true
    Number.isFinite(2e64);      // true
    

    【讨论】:

    【解决方案3】:

    一个简单的n === n+1n === n/0 工作:

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

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

    【讨论】:

    • 这个答案是完全错误的。 n === n+1 对所有大于 2^53 的数字(即 1e30)的计算结果为真。除法破解有效,即使对于 NaN 和 -Infinity 也是如此。但是,LukeH 的回答为您提供了更易读的代码。
    • @tglas 为什么加号是这样的?很高兴这个部门是稳固的。 IMO 我的代码更具可读性和包容性,因为数学比文字更普遍。
    • 因为 IEEE 64 位浮点数有 53 个有效二进制数字(请参阅 en.wikipedia.org/wiki/IEEE_754 ),所以 n+1 无法表示并且需要四舍五入。好吧,即使是整数也会受到舍入误差的影响。顺便说一句,我不认为你的代码是“数学证明”,试试n === n/-0。使用 +/-inf 完成实数时,除非假设基础零序列为正数,否则您的限制没有明确定义。
    • 谢谢@tglas 我永远喜欢 JavaScript 可以被零除 :)
    【解决方案4】:

    实际上 n === n + 1 适用于大于 51 位的数字,例如

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

    【讨论】:

    • 这应该是对 ryanve 的回答的评论。
    • “工作”具有误导性。说“也计算为true。”
    【解决方案5】:

    进行简单的比较:

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

    或保存多个字符:

    Math.abs(number) === Infinity
    

    为什么要使用这个

    1. !(Number.isFinite(number)) 中断 NaN 输入。
    2. Number.POSITIVE_INFINITYNumber.NEGATIVE_INFINITY 可以重新定义;他们是configurable
    3. Infinity-Infinitythe strict mode 中是只读的。
    4. 这是最短的解决方案。

    【讨论】:

      【解决方案6】:

      出于各种防御性编码原因以及可读性,我喜欢使用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
      

      【讨论】:

        【解决方案7】:

        我遇到了一种情况,需要我检查值是否属于 NaNInfinity 类型,但将字符串作为有效结果传递。因为许多文本字符串会产生误报NaN,所以我做了一个简单的解决方案来规避它:

          const testInput = input => input + "" === "NaN" || input + "" === "Infinity";
        
        

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

        所以:

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

        【讨论】:

        • 这篇文章并没有真正处理这里的实际问题,在接受的答案下作为评论会更好。 OP 是关于数字和无穷大,而不是字符串和NaNs 等。
        • 你可能是对的,@code_dredd - 轶事无关紧要。但是解决方案仍然有效:它可以检测到无穷大 - 如果我错了,请纠正我。
        • 这不是重点。已经有一个答案显示了如何正确做到这一点。你所拥有的“工作”仅仅是因为语言本身做了一些愚蠢的事情并且与它管理类型的方式不一致。请避免编写这样的 hack 代码。
        • 如果我改用toString() 会让你更开心吗?随意投反对票或陈述原因,这可能会产生不一致的结果,或者为什么不推荐这种方法。到目前为止,我仍然觉得它为正在寻找答案的人添加了一个选项,并且没有任何具体原因说明这是危险、不稳定等。
        【解决方案8】:

        你可以在窗口中使用isFiniteisFinite(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);
        }
        

        【讨论】:

          猜你喜欢
          • 2017-11-06
          • 1970-01-01
          • 1970-01-01
          • 2011-04-04
          • 2011-07-23
          • 1970-01-01
          • 2016-11-02
          • 2018-04-07
          • 1970-01-01
          相关资源
          最近更新 更多