为什么typeNNN会返回“数字”?

时间:2010-05-10 09:30:32

标签: javascript

出于好奇。

typeof NaN是数字似乎不合逻辑。就像NaN === NaNNaN == NaN返回false一样。这是javascript的特点之一,还是有理由这样做?

编辑:感谢您的回答。尽管让人们感到高兴并不容易。阅读答案和我更了解的维基,但仍然是一个像

这样的句子
  

与NaN进行比较时,即使与自身进行比较,也会返回无序结果。比较谓词是信令或非信令,信令版本表示这种比较的无效例外。等式和不等式谓词是非信令的,因此x = x返回false可用于测试x是否是安静的NaN。

只是让我头晕目眩。如果有人能用人类(而不是数学家)的可读语言翻译,我会感激不尽。

21 个答案:

答案 0 :(得分:97)

好吧,NaN仍然是一个数字类型,尽管它实际上代表的是非数字: - )

NaN只是意味着特定值无法在数字类型的限制内表示(尽管可以说所有必须舍入的数字都适合,但NaN是特殊情况)。

特定NaN不等同于另一个NaN,因为它们可能是不同的值。但是,NaN仍然是数字类型,就像2718或31415一样。


关于你的更新问题,以外行的方式解释:

  

与NaN进行比较时,即使与自身进行比较,也会返回无序结果。比较谓词是信令或非信令,信令版本表示这种比较的无效例外。等式和不等式谓词是非信令的,因此x = x返回false可用于测试x是否是一个安静的NaN。

所有这些意味着(分解为部分):

  

与NaN进行比较时,即使与自身进行比较,也始终会返回无序结果。

基本上,NaN不等于任何其他数字,包括另一个NaN,甚至包括本身

  

比较谓词是信令或非信令,信令版本表示此类比较的无效例外。

尝试在NaN和另一个数字之间进行比较(小于,大于等)操作可能导致抛出异常(信令)或者仅仅导致结果为假(非信号或安静)。

  

等式和不等式谓词是非信令的,因此x = x返回false可用于测试x是否是一个安静的NaN。

测试相等(等于,不等于)永远不会发出信号,因此使用它们不会导致异常。如果您有常规号码x,则x == x将始终为真。如果xNaN,则x == x将始终为false。它为您提供了一种轻松(安静地)检测NaN的方法。

答案 1 :(得分:47)

这意味着不是数字。它不是javascript的特性,而是普通的计算机科学原理。

来自http://en.wikipedia.org/wiki/NaN

  

有三种操作   返回NaN:

     

使用NaN作为至少一个操作数的操作

     

不确定表格

     
      
  • 划分0/0,∞/∞,∞/-∞,-∞/∞和-∞/-∞
  •   
  • 乘法0×∞和0×-∞
  •   
  • 权力1 ^∞
  •   
  • 加法∞+( - ∞),( - ∞)+∞和等效减法。
  •   
     

结果复杂的实际操作:

     
      
  • 负数的平方根
  •   
  • 负数的对数
  •   
  • 90度(或π/ 2弧度)的奇数倍的切线
  •   
  • 数字的反正弦或余弦,小于-1或   大于+1。
  •   

所有这些值可能不一样。对NaN的简单测试是测试value == value是错误的。

答案 2 :(得分:16)

ECMAScript(JavaScript)标准指定NumbersIEEE 754个浮点数,其中包含NaN作为可能值。

  

ECMA 262 5e Section 4.3.19:数值

     

原始值对应于双精度64位二进制格式IEEE 754值。

  

ECMA 262 5e Section 4.3.23:NaN

     

数值,即IEEE 754“非数字”值。

  维基百科上的

IEEE 754

     

IEEE浮点运算标准是由电气和电子工程师协会建立的技术标准,也是最广泛使用的浮点运算标准[...]

     

标准定义

     
      
  • 算术格式:二进制和十进制浮点数据集,由有限数(包括有符号零和次正规数),无穷大和特殊“非数字”值组成(NaN的)
  •   
     

[...]

答案 3 :(得分:7)

typeof NaN返回'number'因为:

  • ECMAScript规范说数字类型包括NaN:

      

    4.3.20 Number type

         

    所有可能的数值的集合,包括特殊的“非数字”   (NaN)值,正无穷大和负无穷大

  • 所以typeof会相应地返回:

      

    <强> 11.4.3 The typeof Operator

         

    制作 UnaryExpression typeof UnaryExpression 是   评估如下:

         
        
    1. val 成为评估 UnaryExpression 的结果。
    2.   
    3. 如果Type val )为Reference,那么   
          
      1. 如果IsUnresolvableReference val )为 true ,请返回"undefined"
      2.   
      3. val GetValue val )。
      4.   
    4.   
    5. 根据表20返回由Type val )确定的字符串。
        
    6.         

                      Table 20 — typeof Operator Results
      ==================================================================
      |        Type of val         |              Result               |
      ==================================================================
      | Undefined                  | "undefined"                       |
      |----------------------------------------------------------------|
      | Null                       | "object"                          |
      |----------------------------------------------------------------|
      | Boolean                    | "boolean"                         |
      |----------------------------------------------------------------|
      | Number                     | "number"                          |
      |----------------------------------------------------------------|
      | String                     | "string"                          |
      |----------------------------------------------------------------|
      | Object (native and does    | "object"                          |
      | not implement [[Call]])    |                                   |
      |----------------------------------------------------------------|
      | Object (native or host and | "function"                        |
      | does implement [[Call]])   |                                   |
      |----------------------------------------------------------------|
      | Object (host and does not  | Implementation-defined except may |
      | implement [[Call]])        | not be "undefined", "boolean",    |
      |                            | "number", or "string".            |
      ------------------------------------------------------------------
      

此行为符合IEEE Standard for Floating-Point Arithmetic (IEEE 754)

  

4.3.19 Number value

     

对应于双精度64位二进制的原始值   格式IEEE 754值

     

4.3.23 NaN

     

数字值是IEEE 754“非数字”值

     

8.5 The Number Type

     

数字类型恰好是18437736874454810627(即2 53 -2 64 +3)   值,表示双精度64位格式IEEE 754   IEEE二进制浮点标准中规定的值   算术,除了9007199254740990(即2 53 -2)之外   IEEE标准的“非数字”值表示为   ECMAScript作为单个特殊的 NaN 值。 (注意 NaN 值   由程序表达式NaN生成。)

答案 4 :(得分:5)

NaN是有效的浮点值(http://en.wikipedia.org/wiki/NaN

和NaN === NaN是假的,因为它们不一定是相同的非数字

答案 5 :(得分:5)

NaN != NaN因为他们不需要SAME非号码。因此它很有意义...... 另外为什么花车的+0.00和-0.00都不一样。舍入可能会使它们实际上不为零。

至于typeof,这取决于语言。并且大多数语言会说NaN是浮点数,双精度数或数字取决于它们如何对它进行分类...我知道没有语言可以说这是一个未知类型或null。

答案 6 :(得分:4)

NaN代表Not a Number。它是数值数据类型的值(通常是浮点类型,但不总是),表示无效操作的结果,例如除以零。

虽然它的名称表明它不是数字,但用于保存它的数据类型是数字类型。因此,在JavaScript中,要求NaN的数据类型将返回number(正如alert(typeof(NaN))清楚地证明的那样)。

答案 7 :(得分:2)

NaN更好的名称,更准确,更容易混淆地描述其含义,将是数字异常。它实际上是另一种异常对象,伪装成具有原始类型(通过语言设计),同时它在虚假的自我比较中不被视为原始的。从此混乱。只要语言&#34;不会成功,#34;要在适当的异常对象原始数字之间进行选择,混淆将会存在。

NaN与其自身的臭名昭着的不平等,=====都是将此异常对象强制为原始类型的混乱设计的表现形式。这打破了原语由其值唯一确定的基本原则。如果NaN被视为例外(其中可能有不同种类),那么它不应该被出售&#34;原始的。如果它想成为原始的那个原则必须坚持下去。只要它被打破,就像我们在JavaScript中一样,并且我们无法在两者之间做出真正的决定,那么导致所涉及的每个人的不必要的认知负荷的混乱将保持不变。然而,通过简单地在两者之间做出选择,这很容易解决:

  • 使NaN成为一个特殊的异常对象,其中包含有关异常如何产生的有用信息,而不是像当前实现的那样抛弃那些信息,从而导致难以调试的代码;
  • 或使NaN成为原始类型number的实体(可能不那么令人困惑地称为&#34;数字&#34;),在这种情况下它应该等于它自己并且不能包含任何其他信息;后者显然是一个低劣的选择。

NaN强制转换为number类型的唯一可能的优点是能够将其重新放回任何数值表达式。但是,这会使其成为一种脆弱的选择,因为包含NaN的任何数值表达式的结果将为NaN,或导致不可预测的结果,例如NaN < 0评估为false ,即返回boolean而不是保留异常。

即使&#34;事情是他们的方式&#34;,没有什么能阻止我们为自己做出明确的区分,以帮助我们的代码更可预测,更容易调试。实际上,这意味着识别这些例外并将其作为例外处理。遗憾的是,这意味着更多的代码,但希望通过Typetype of Flowtype等工具来缓解这些代码。

然后我们有了凌乱的quiet vs noisy aka signalling NaN distinction。这实际上是关于如何处理异常,而不是异常本身,与其他异常没什么不同。

同样,Infinity+Infinityextension of the real line中出现的数字类型的元素,但它们不是实数。在数学上,它们可以由收敛到+-Infinity的实数序列表示。

答案 8 :(得分:2)

Javascript使用NaN来表示它遇到的任何无法通过其规范以任何其他方式表示的内容。这并不意味着它不是一个数字。这只是描述遭遇的最简单方法。 NaN意味着它或引用它的对象无法通过javascript以任何其他方式表示。出于所有实际目的,它是“未知的”。作为'未知',它无法告诉你它是什么,即使它本身也是如此。它甚至不是它所分配的对象。它只能告诉你它不是什么,并且只能用编程语言在数学上描述无关或虚无。由于数学是关于数字的,因此javascript代表NaN的虚无。这并不意味着它不是一个数字。这意味着我们无法以任何其他有意义的方式阅读它。这就是为什么它甚至不能平等。因为它没有。

答案 9 :(得分:1)

因为NaN是数字数据类型。

答案 10 :(得分:1)

如果使用jQuery,我更喜欢isNumeric而不是检查类型:

console.log($.isNumeric(NaN));  // returns false
console.log($.type(NaN));       // returns number

http://api.jquery.com/jQuery.isNumeric/

答案 11 :(得分:1)

从类型的角度来看,

NaN是一个数字,但不是正常数字,如1,2或329131.名称“非数字”指的是表示的值是特殊的,是关于IEEE格式规范域,而不是javascript语言域。

答案 12 :(得分:1)

考虑NAN的最佳方式是它不是已知数字。这就是NAN!= NAN的原因,因为每个NAN值代表一些唯一的未知数字。 NAN是必要的,因为浮点数具有有限的值范围。在某些情况下,舍入发生在较低位丢失的地方,这导致看起来像1.0 / 11 * 11!= 1.0的无意义。非常大的值是更大的NAN,无限是一个完美的例子。

鉴于我们只有10个手指,任何尝试显示大于10的值都是不可能的,这意味着这些值必须是NAN,因为我们已经丢失了大于10的值的真实值。浮点值也是如此,其值超过了浮点数的限制。

答案 13 :(得分:1)

这只是因为NaN是JS中Number对象的属性,它与数字无关。

答案 14 :(得分:0)

NaN仍然是数字类型,但它代表的值不能代表有效数字。

答案 15 :(得分:0)

我们可以说NaN是一个特殊的案例对象。在这种情况下,NaN的对象代表一个没有数学意义的数字。数学中还有一些其他特殊情况对象,如INFINITE等。

你仍然可以用它做一些计算,但这会产生奇怪的行为。

此处有更多信息:http://www.concentric.net/~ttwang/tech/javafloat.htm(基于java,不是javascript)

答案 16 :(得分:0)

你必须喜欢Javascript。它有一些有趣的小怪癖。

http://wtfjs.com/page/13

如果你停下来逻辑地解决它们,或者如果你对数论有所了解,那么大多数的怪癖都可以解释,但是如果你不了解它们,它们仍然可以把你赶出去。

顺便说一句,我建议阅读剩余的http://wtfjs.com/ - 有比这更有趣的怪癖!

答案 17 :(得分:0)

值NaN实际上是Number.NaN因此当你问它是否是数字时它会说是。你通过使用isNaN()调用做了正确的事情。

有关信息,NaN也可以通过对未定义的数字的操作返回,如零或负数的平方根。

答案 18 :(得分:0)

Number类型的特殊值为POSITIVE_INFINITY

为什么呢?按设计

答案 19 :(得分:0)

Javascript只有一种数字数据类型,即标准的64位双精度浮点数。一切都是双重的。 NaN是double的特殊值,但它仍然是双倍的。

parseInt所做的就是将您的字符串“强制转换”为数字数据类型,因此结果是始终“数字”;只有当原始字符串不可解析时,其值才为NaN。

答案 20 :(得分:-1)

一个例子

想象一下我们正在将字符串转换为数字:

Number("string"); // returns NaN

我们将数据类型更改为数字,但其值不是数字!