关于javascript:为什么typeof NaN会返回’number’?

Why does typeof NaN return 'number'?

只是出于好奇。

typeof NaN是数字似乎不太合乎逻辑。就像NaN === NaNNaN == NaN返回错误一样。这是JavaScript的一个特性,还是有理由这样做?

编辑:谢谢你的回答。不过,要想让人们清醒过来可不是件容易的事。阅读答案和维基,我了解的更多,但仍然是这样一个句子

A comparison with a NaN always returns an unordered result even when comparing with itself. The comparison predicates are either signaling or non-signaling, the signaling versions signal an invalid exception for such comparisons. The equality and inequality predicates are non-signaling so x = x returning false can be used to test if x is a quiet NaN.

只是让我的头转个不停。如果有人能用人类(比如数学家)可读的语言来翻译,我会感激的。


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

NaN只是表示特定值不能在数值类型的限制范围内表示(尽管对于所有必须四舍五入才能适应的数字都可以这样说,但NaN是一种特殊情况)。

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

关于你更新后的问题,用外行的术语解释:

A comparison with a NaN always returns an unordered result even when comparing with itself. The comparison predicates are either signalling or non-signalling, the signalling versions signal an invalid exception for such comparisons. The equality and inequality predicates are non-signalling so x = x returning false can be used to test if x is a quiet NaN.

所有这些手段都是(分解为若干部分):

A comparison with a NaN always returns an unordered result even when comparing with itself.

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

The comparison predicates are either signalling or non-signalling, the signalling versions signal an invalid exception for such comparisons.

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

The equality and inequality predicates are non-signalling so x = x returning false can be used to test if x is a quiet NaN.

相等性测试(等于、不等于)从不发出信号,因此使用它们不会导致异常。如果你有一个固定的数字x,那么x == x将永远是正确的。如果xNaN的话,那么x == x总是错误的。它给了你一种轻松(安静)检测NaN的方法。


它的意思不是数字。它不是javascript的一个特性,而是普通的计算机科学原理。

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

There are three kinds of operation
which return NaN:

Operations with a NaN as at least one operand

Indeterminate forms

  • The divisions 0/0, ∞/∞, ∞/?∞, ?∞/∞, and ?∞/?∞
  • The multiplications 0×∞ and 0×?∞
  • The power 1^∞
  • The additions ∞ + (?∞), (?∞) + ∞ and equivalent subtractions.

Real operations with complex results:

  • The square root of a negative number
  • The logarithm of a negative number
  • The tangent of an odd multiple of 90 degrees (or π/2 radians)
  • The inverse sine or cosine of a number which is less than ?1 or
    greater than +1.

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


ecmascript(javascript)标准指定Numbers是ieee 754浮点数,其中可能包含NaN

ECMA 262 5e Section 4.3.19: Number value

primitive value corresponding to a double-precision 64-bit binary format IEEE 754 value.

ECMA 262 5e Section 4.3.23: NaN

Number value that is a IEEE 754"Not-a-Number" value.

IEEE 754 on Wikipedia

The IEEE Standard for Floating-Point Arithmetic is a technical standard established by the Institute of Electrical and Electronics Engineers and the most widely used standard for floating-point computation [...]

The standard defines

  • arithmetic formats: sets of binary and decimal floating-point data, which consist of finite numbers (including signed zeros and subnormal numbers), infinities, and special"not a number" values (NaNs)

[...]


typeof NaN返回'number'是因为:

  • ECMAScript规范指出,数字类型包括NaN:


    4.3.20 Number type

    set of all possible Number values including the special"Not-a-Number"
    (NaN) values, positive infinity, and negative infinity

  • 因此,typeof相应地返回:


    11.4.3 The typeof Operator

    The production UnaryExpression : typeof UnaryExpression is
    evaluated as follows:

  • Let val be the result of evaluating UnaryExpression.
  • If Type(val) is Reference, then

  • If IsUnresolvableReference(val) is true, return "undefined".
  • Let val be GetValue(val).
  • Return a String determined by Type(val) according to Table 20.
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
                    Table 20typeof 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 Number value

primitive value corresponding to a double-precision 64-bit binary
format IEEE 754 value

4.3.23 NaN

number value that is a IEEE 754"Not-a-Number" value

8.5 The Number Type

The Number type has exactly 18437736874454810627 (that is, 253?264+3)
values, representing the double-precision 64-bit format IEEE 754
values as specified in the IEEE Standard for Binary Floating-Point
Arithmetic, except that the 9007199254740990 (that is, 253?2) distinct
"Not-a-Number" values of the IEEE Standard are represented in
ECMAScript as a single special NaN value. (Note that the NaN value
is produced by the program expression NaN.)


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

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


NaN != NaN,因为它们不需要相同的非数字。所以这很有意义…另外,为什么浮点数的+0.00和-0.00都不相同。四舍五入可能会使它们实际上不是零。

至于类型,那取决于语言。大多数语言都会说NaN是一个浮点、双精度或数字,这取决于它们如何分类…我不知道会说这是未知类型或空的语言。


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

虽然它的名称表示它不是数字,但用于保存它的数据类型是数字类型。因此,在javascript中,请求NaN的数据类型将返回number(如alert(typeof(NaN))所清楚显示的那样)。


(P)A better name for EDOCX1 original 0,describing its meaning more precisely and less confusingly,would be a numerical exception.它实际上是另一种类型的例外情况,因为它具有原始的类型(通过语言设计),在这种情况下,它本身并不是一种原始的自我比较。混乱之时而且,随着语言的发展,"将不会使你的头脑"在优先的例外目标和原始编号之间摇摆不定。(p)(P)The infanmous non-equality of EDOCX1 commercial 0 to itself,both EDOCX1 original 2 and EDOCX1 original 3 commercial is a manifation of the confusing design forcing this exception object into being a primive type.这违反了一项基本原则,即一个原始人是由其价值决定的。如果EDOCX1 o nivers is preferred to be seen as exception(of which there can be different kinds),它们就不应是原始的"焊"。and if it is wanted to be privative,that principle must hold.As long as it is broken,as we have in Javascript,and we can't really decide between the two,the confusion leading to unnecessary认知load for everyone involved will remain.然而,这是真正的轻松到fix by simply making the choice between the two:(p)

  • Either make EDOCX1 pental 0 a special exception object containing the useful information about how the exception arose,as opposed to throwing that information away as what is currently implemented,leading to harder-to-debug code;
  • Or make EDOCX1 substantive type EDOCX1 original 7(that could be less confusingly called"numeric"),in which case it should be equal to itself and cannot contain any other information;the latter is clearly an lower choice.

(P)The only conceivable advantage of forcing EDOCX1 indicatual 0 into EDOCX1 original 7.Type is being able to throw it back into any numerical expression.Which,however,makes it Brittle choice,because the result of any numerical expression containing EDOCX1 niplication 0 will either be EDOCX1 universifical 0,or leading to unredicatible results such as EDOCX1 indicatual 12.Evaluating to EDOCX1/13,I.E.Returning EDOCX1/Instead of keeping the exception.(p)(P)And even if"things are the way they are",nothing prevents us from making that clear distinction for ourselves,to help make our code more predictable and easierly debuggable.In practice,that means identifying those exceptions and dealing with them as exceptions.这是一个机会,意味着更多的守则,但希望是可以通过一些工具来减轻的,这些工具是关于流动性的。(p)(P)而我们有一个消息静静地对大声的AKA signalling EDOCX1Which really is about how exceptions are handled,not the exceptions themselves,and nothing different from other exceptions.(p)(P)Similarly,EDOCX1 penographic 16 silian and EDOCX1 penographic 17 nable are elements of numeric type arising in the extension of the real line but they are not real numbers.Mathematically,they can be represented by sequences of real numbers converging to either EDOCX1(p)


JavaScript使用NaN来表示它遇到的任何东西,而这些东西不能通过它的规范以任何其他方式表示。这并不意味着它不是一个数字。这只是描述这次相遇最简单的方式。nan意味着它或引用它的对象不能以任何其他方式由javascript表示。就所有实际目的而言,这是"未知的"。因为"未知",它不能告诉你它是什么,即使它本身也是。它甚至不是分配给它的对象。它只能告诉你它不是什么,而不是无或虚无只能用编程语言进行数学描述。因为数学是关于数字的,所以javascript将虚无表示为NaN。这并不意味着它不是一个数字。这意味着我们不能以任何其他有意义的方式来阅读它。这就是为什么它连自己都不能平等的原因。因为没有。


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


认为南的最好方法是它不是一个已知的数字。这就是为什么!=NaN,因为每个NaN值代表一些唯一的未知数字。NaN是必需的,因为浮点数字的值范围有限。在某些情况下,四舍五入发生在较低的位丢失的地方,这导致了看起来像1.0/11*11这样的胡说八道!= 1。真正大的值,更大的是纳米与无限是一个完美的例子。

如果我们只有十根手指,任何显示大于10的值的尝试都是不可能的,这意味着这些值必须是NaN,因为我们已经失去了大于10的值的真实值。浮点数也是如此,其中的值超过了浮点数可以保持的范围。


因为NaN是数字数据类型。


从类型的角度来看,NaN是一个数字,但不是像1、2或329131那样的正常数字。名称"不是数字"是指所表示的值是特殊的,并且是关于IEEE格式规范域,而不是JavaScript语言域的。


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

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

http://api.jquery.com/jquery.isnumeric/


它是数字类型的特殊值,为正无穷大

为什么?按设计


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

parseInt所做的就是将字符串"强制转换"为数字数据类型,因此结果总是"数字";只有原始字符串不可解析时,它的值才会是NaN。


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

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

更多信息:http://www.同心.NET/TWang/Tea/JavaFoLa.HTM(基于Java,而不是JavaScript)


你一定很喜欢javascript。它有一些有趣的小怪癖。

http://wtfjs.com/page/13

如果你停下来按逻辑来解决这些怪癖,或者你对数论有点了解,大多数怪癖都可以解释出来,但是如果你不了解它们,它们仍然可以把你抓住。

顺便说一句,我建议你读一下http://wtfjs.com/-有比这个有趣得多的怪癖!


NaN值实际上是数字。因此当您询问它是否是数字时,它会说是。您使用isnan()调用完成了正确的操作。

对于信息,还可以通过对数字的操作返回NaN,这些操作与负数的零除或平方根除不同。


NaN仍然是数字类型,但它表示无法表示有效数字的值。


An example(P)想象一下,我们将成为一个数字:(p)字母名称(P)We changed the data type to number but its value is not a number!(p)