为什么 typeof NaN 返回“数字”?

IT技术 javascript nan
2021-01-25 21:57:54

只是出于好奇。

typeof NaN数字似乎不太合乎逻辑顺便说一下,就像NaN === NaNNaN == NaN返回 false一样这是 javascript 的特性之一,还是有原因?

编辑:感谢您的回答。然而,让人们转过头来并不是一件容易的事情。阅读答案和维基我了解更多,但仍然是这样的一句话

与 NaN 的比较总是返回一个无序的结果,即使与它自己比较时也是如此。比较谓词是信令或非信令,信令版本为此类比较发出无效异常信号。等式和不等式谓词是无信号的,因此返回 false 的 x = x 可用于测试 x 是否为安静的 NaN。

只是让我的头旋转。如果有人可以用人类(而不是数学家)可读的语言翻译它,我将不胜感激。

6个回答

好吧,将称为“非数字”的东西视为数字,但NaN仍然是数字类型,这似乎有点奇怪,尽管如此:-)

NaN只是意味着无法在数字类型的限制范围内表示特定值(尽管对于必须四舍五入以适合的所有数字,但这NaN是一种特殊情况)。

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


至于你更新的问题,用外行的话解释:

与 NaN 的比较总是返回一个无序的结果,即使与它自己比较时也是如此。比较谓词是信令或非信令,信令版本为此类比较发出无效异常信号。等式和不等式谓词是无信号的,因此返回 false 的 x = x 可用于测试 x 是否为安静的 NaN。

所有这些都意味着(分解成几个部分):

与 NaN 的比较总是返回一个无序的结果,即使与它自己比较时也是如此。

基本上, aNaN不等于任何其他数字,包括 another NaN,甚至包括它自己

比较谓词是信令或非信令,信令版本为此类比较发出无效异常信号。

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

等式和不等式谓词是无信号的,因此返回 false 的 x = x 可用于测试 x 是否为安静的 NaN。

相等性测试(等于、不等于)永远不会发出信号,因此使用它们不会导致异常。如果您有一个常规数字x,那么x == x将始终为真。如果x是 a NaN,则x == x永远为假。它为您提供了一种NaN轻松(安静)检测的方法

很好的解释,尽管我不同意最后两句话:检查 x 是否为 NaN 的更好方法是使用 isNaN() 函数
2021-03-23 21:57:54
@DominicRodger 这就是我的想法:typeof a === 'number'意思是“a 在内部存储为 IEEE 754 浮点数”
2021-03-29 21:57:54
@Hashem,很可能是因为它们被认为是相同的无穷大。将除法视为重复减法,无论从 2 开始还是从 1 开始都没有区别,达到(或更准确地说,达到)零所需的步数相同我知道数学大师确实不同类别的无穷大,但是 (1) 我怀疑1/0并且2/0处于同一类别中,并且 (2) 在 IEEE754 中只有一类无穷大(+/-当然除外)。
2021-03-29 21:57:54
如果 an可以由不同的值产生,为什么会Infinity === Infinity返回:1.0 / 0.0 或 2.0 / 0.0?trueInfinity
2021-04-04 21:57:54
我不知道有什么方法可以以任何有意义的方式定义这些特殊的“实际数字”。在数学中,对数和负数的根只能通过将实数扩展到复数来获得,在复数中它们评估为多个值,并且0/0没有以任何有意义的方式定义,除了说它的“值”是整个集合的数字。即使它们被定义,Math.log(-1) == Math.log(-1)仍然计算为false. 因此,不仅没有“实际数字”,NaN而且即使有,它们也没有用于比较。
2021-04-06 21:57:54

这意味着不是一个数字。它不是 javascript 的特性,而是常见的计算机科学原理。

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

有三种返回 NaN 的操作:

以 NaN 作为至少一个操作数的操作

不确定形式

  • 除法 0/0、∞/∞、∞/−∞、−∞/∞ 和 −∞/−∞
  • 0×∞ 和 0×−∞ 乘法
  • 幂 1^∞
  • 加法 ∞ + (−∞)、(−∞) + ∞ 和等效减法。

具有复杂结果的实际操作:

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

所有这些值可能并不相同。对 NaN 的一个简单测试是测试value == value是否为假。

看起来你是对的,@Andy。现在这是一个特点。
2021-03-13 21:57:54
一个更简单的测试是 isNaN(value)
2021-03-14 21:57:54
短语“这些值可能不相同”没有意义,因为这些值不存在。
2021-03-18 21:57:54
@Alsciende 但它并不等效。 isNaN(undefined)返回true,但undefined == undefined也是如此。除了null.
2021-04-04 21:57:54
换句话说,value !== value可能是测试 if valueis true的最短方法NaN
2021-04-05 21:57:54

ECMAScript (JavaScript) 标准指定NumbersIEEE 754浮点数,其中包括NaN一个可能的值。

ECMA 262 5e 第 4.3.19 节:数值

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

ECMA 262 5e 第 4.3.23 节:NaN

作为 IEEE 754“非数字”值的数字值。

维基百科上的IEEE 754

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

该标准定义了

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

[...]

typeof NaN返回,'number'因为:

  • ECMAScript 规范说 Number 类型包括 NaN:

    4.3.20 号码类型

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

  • 因此相应地typeof返回:

    11.4.3 运算符的类型

    产生式UnaryExpression : typeof UnaryExpression的计算方式如下:

    1. val为评估UnaryExpression的结果
    2. 如果Type ( val ) 是Reference,则
      1. 如果IsUnresolvableReference ( val ) 为,则返回"undefined"
      2. valGetValue ( val )。
    3. 返回字符串确定由类型VAL根据表20)。

                    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 浮点算术标准 (IEEE 754)

4.3.19 数值

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

4.3.23 南

作为 IEEE 754“非数字”值的数字值

8.5 号码类型

Number 类型正好有 18437736874454810627(即 2 53 -2 64 +3)个值,表示 IEEE 二进制浮点运算标准中指定的双精度 64 位格式 IEEE 754 值,除了 900714909204也就是说,IEEE 标准的2 53 -2) 个不同的“非数字”值在 ECMAScript 中表示为单个特殊NaN值。(注意NaN值是由程序表达式产生的NaN。)

NaN != NaN因为它们不需要相同的非数字。因此它很有意义......还有为什么浮点数有 +0.00 和 -0.00 不一样。四舍五入可能会使它们实际上不为零。

至于typeof,这取决于语言。大多数语言会说 NaN 是浮点数、双精度数或数字,具体取决于它们的分类方式……我知道没有任何语言会说这是未知类型或空值。

呃,考虑: var x = parseInt('no dice'), y = x; 现在我会说两个 NaN 是完全一样的?但是不, x === y 也返回 false 。
2021-03-22 21:57:54
是的,但您不能确定,因此它们不一样。它与数据库中的 NULLable 逻辑相同。尽管很多人认为它们与来自其他编程语言的空指针相同,但它们实际上具有完全不同的语义。它们是“未知的”,因此一个 NULL 值与另一个值相比总是假的。对 NULL 值进行计算的结果是 NULL。尝试从被称为 UNKNOWN 的值的角度来看它
2021-03-24 21:57:54
作为 type numberNaN是原始的,因此由它的值唯一确定。
2021-04-07 21:57:54