为什么键入NaN返回“数字”?

只是出于好奇。

typeof NaN是编号似乎不是很合乎逻辑。 就像NaN === NaNNaN == NaN顺便返回false。 这是JavaScript的特性之一,还是会有这个原因呢?

编辑:谢谢你的答案。 尽pipe如此,让他们头脑不是一件容易的事情。 阅读答案和维基我更了解,但仍然是一个像

与NaN的比较总是返回一个无序的结果,即使与自己比较。 比较谓词是信令或非信令,信令版本表示这种比较的无效例外。 等式和不等式谓词是非信号的,所以x = x返回false可以用来testingx是否是安静的NaN。

只是让我的头旋转。 如果有人能把这个翻译成人类(而不是math家)可读的语言,那么我将会很有成就感。

这意味着不是一个数字。 这不是javascript的一个特点,而是一般的计算机科学原理。

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

有三种返回NaN的操作:

使用NaN作为至less一个操作数

不确定的forms

  • 分0/0,∞/∞,∞/-∞,-∞/∞和-∞/-∞
  • 乘法0×∞和0×∞
  • 功率1 ^∞
  • 加∞+(-∞),(-∞)+∞和等价减法。

实际操作复杂的结果:

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

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

那么, NaN仍然是一个数字types ,尽pipe它实际上代表了非数字:-)

NaN只是意味着特定的值不能在数字types的限制内表示(尽pipe对于所有必须四舍五入以适合的数字可以这么说,但是NaN是特殊情况)。

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


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

与NaN的比较总是返回一个无序的结果,即使与自己比较。 比较谓词是信令或非信令,信令版本表示这种比较的无效例外。 等式和不等式谓词是非信号的,所以x = x返回false可以用来testingx是否是安静的NaN。

所有这些意思是(分解成部分):

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

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

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

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

等式和不等式谓词是非信号的,所以x = x返回false可以用来testingx是否是安静的NaN。

testing相等(等于,不等于)不会发出信号,所以使用它们不会引起exception。 如果你有一个规则的数字x ,那么x == x将始终为真。 如果xNaN ,那么x == x将始终为假。 它给你一个轻松(安静地)检测NaN的方法。

ECMAScript(JavaScript)标准指定Numbers是IEEE 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规范说数字types包括NaN:

    4.3.20号码types

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

  • 所以typeof返回:

    11.4.3操作员的types

    生产UnaryExpressiontypeof UnaryExpression的计算方法如下:

    1. val是评估UnaryExpression的结果。
    2. 如果types ( val )是引用 ,那么
      1. 如果IsUnresolvableReference ( val )为true ,则返回"undefined"
      2. val是GetValue ( val )。
    3. 根据表20返回Type ( val )确定的string。
      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 NaN

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

8.5数字types

Numbertypes正好具有18437736874454810627(即2 53 -2 64 +3)个值,表示双精度64位格式IEEE 754值,如IEEE二进制浮点algorithm标准中所规定的,不同之处在于9007199254740990(也就是2 53 -2)IEEE标准中不同的“非数字”值在ECMAScript中表示为一个特殊的NaN值。 (请注意, NaN值由程序expression式NaN 。)

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

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

NaN != NaN因为它们不需要同一个非数字。 因此它有很大的意义……同样为什么花车有+0.00和-0.00是不一样的。 舍入可能会做,他们实际上不是零。

至于typeof,则取决于语言。 而大多数语言会说,NaN是一个浮点数,双精度或数字,取决于它们如何分类…我知道没有语言会说这是一个未知的types或null。

NaN代表不是数字 。 它是一个数值数据types的值(通常是浮点types,但并不总是),表示无效操作的结果,例如除以零。

虽然它的名字表示它不是一个数字,但是用来保存它的数据types是一个数字types。 所以在JavaScript中,要求NaN的数据types将返回number (如alert(typeof(NaN))清楚地表明)。

JavaScript使用NaN来表示它遇到的任何其他方式不能用其规范来表示的东西。 这并不意味着它不是一个数字。 这只是描述遇到的最简单的方法。 NaN意味着它或者一个引用它的对象不能以任何其他方式用javascript表示。 实际上,这是“未知的”。 “未知”,它不能告诉你它是什么,即使它本身。 它甚至不是它分配给的对象。 它只能告诉你它不是什么东西,而不能用编程语言在math上描述。 由于math是关于数字的,JavaScript代表虚无作为NaN。 这并不意味着它不是一个数字。 这意味着我们不能以任何有意义的方式来阅读它。 这就是为什么它甚至不能自己平等。 因为它没有。

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

想想NAN的最好方法就是它不是一个已知的数字。 这就是为什么NA​​N!= NAN,因为每个NAN值代表一些独特的未知数。 NAN是必要的,因为浮点数的值范围有限。 在某些情况下,舍入发生在低位丢失的地方,导致看起来象1.0 / 11 * 11!= 1.0这样的无意义。 无限大的NAN是一个很好的例子。

由于我们只有十个手指,所以试图显示大于10的值是不可能的,这意味着这样的值必须是NAN,因为我们已经失去了这个大于10的值的真值。 浮点值也是如此,其中的值超过了浮点数的限制。

NaN是从types的angular度来看的一个数字,但不是像1,2或329131这样的正常数字。名称“不是数字”是指所表示的值是特殊的并且是关于IEEE格式规范域的事实,不是JavaScript语言的域名。

NaN一个更好的名字,更精确地描述它的含义,不那么容易混淆,这将是一个数值例外 。 它实际上是另一种被伪装成具有原始types(通过语言devise)的exception对象,同样在它的错误的自我比较中它不被视为原始的。 从哪里混乱。 而只要语言“无法自主”在适当的例外对象原始数字之间进行select,混乱就会停滞不前。

NaN对自身的臭名昭着的不平等, =====都是令人困惑的devise的performance,强制这个exception对象成为一种原始types。 这打破了一个基本原则,即一个原始的价值是唯一确定的 。 如果NaN被视为例外(其中可能有不同的种类),那么它就不应该被当作原始的“销售”。 如果想成为原始的,那么这个原则就成立了。 只要JavaScript有问题,而且我们无法在两者之间做出真正的决定,那么导致所有相关人员的不必要的认知负担的混乱依然存在。 然而,通过简单地在两者之间进行select,这确实很容易解决:

  • 要么使NaN成为一个特殊的exception对象,其中包含有关如何产生exception的有用信息,而不是像当前实现的那样抛弃这些信息,导致难以debugging的代码;
  • 或者使NaN成为原始typesnumber一个实体(可能不那么容易被称为“数字”),在这种情况下,它应该与自身相等并且不能包含任何其他信息; 后者显然是一个劣等的select。

强制NaN进入numbertypes的唯一可能的好处是能够将其重新用于任何数字expression式。 然而,这使得它很脆弱的select,因为任何包含NaN数字expression式的结果将是NaN ,或导致不可预知的结果,如NaN < 0评估为false ,即返回boolean而不是保持exception。

即使“事情是这样”,也没有什么能阻止我们为自己做出明确的区分,帮助我们的代码更可预测,更容易debugging。 在实践中,这意味着确定这些例外情况并将其作为例外处理。 不幸的是,这意味着更多的代码,但希望可以通过诸如Flowtype的TypeScript之类的工具来缓解。

然后,我们有了凌乱的安静与嘈杂的又名信号NaN区别 。 究竟是如何处理exception,而不是exception本身,与其他exception没有什么不同。

同样, Infinity+Infinity数字types的元素,在实线的扩展中出现,但它们不是实数。 在math上,它们可以用收敛于+-Infinity的实数序列表示。

JavaScript只有一个数字数据types,这是标准的64位双精度浮点数。 一切都是双重的。 NaN是双倍的特殊价值,但它是双倍的。

parseInt所做的就是将你的string“转换”为一个数字数据types,所以结果总是 “数字”。 只有当原始string不可parsing时,其值才会是NaN。

数字types的特殊值是POSITIVE_INFINITY

为什么? 按devise

NaN仍然是一个数字types,但它代表的值不能表示一个有效的数字。

因为NaN是一个数字数据types。

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

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

更多信息在这里: http : //www.concentric.net/~ttwang/tech/javafloat.htm (基于Java,不是JavaScript)

你必须爱上Javascript。 它有一些有趣的小怪癖。

http://wtfjs.com/page/13

大部分的怪癖可以从逻辑上停下来解释,或者如果你对数论有一定的了解,但是如果你不了解它们的话,它们仍然可以把你赶出去。

顺便说一句,我build议阅读http://wtfjs.com/的其余部分; – 这里有更多有趣的怪癖!

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

有关信息,NaN也可以通过对数字进行操作来返回,这些数字没有像零或负数的平方根那样被分割。

如果使用jQuery,我更喜欢isNumeric检查types:

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

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