只是出于好奇。

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

编辑:感谢您的回答。但是,要让所有人适应现实并非易事。阅读答案和Wiki我理解得更多,但是,像


这样的句子与NaN进行比较,即使与自身进行比较,也总是返回无序的结果。比较谓词是信令或非信令,信令版本表示此类比较的无效异常。等式和不等式谓词是无信号的,因此x = x返回false可以用来测试x是否为安静的NaN。


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

评论

+1:“ NaN是一个数字,但不是一个数字。哼……什么?!”

为了额外的乐趣; (NaN!== NaN)== true

更有趣(但可以理解,isNaN返回一个布尔值):isNaN(parseInt('nodice'))=== isNaN(parseInt('someOtherNaN'))=== true;

如果使用jQuery,我更喜欢isNumeric而不是检查类型:$ .isNumeric(NaN);返回false,其中以$ .type(NaN);的形式返回数字。 api.jquery.com/jQuery.isNumeric

作为专业数学家,我必须说句子与精确的数学语言几乎没有共同之处。

#1 楼

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

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


有三种返回NaN的运算


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

不定形式


除法0/0,∞/∞,∞/-∞,-∞/∞和-∞/-∞
乘法0×∞和0×-∞
幂1 ^∞
加法∞+(-∞),(-∞)+∞和等效减法。

具有复杂结果的实际运算:


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



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

评论


甚至更简单的测试是isNaN(value)

– Alsciende
2010年5月10日14:12

@Alsciende虽然不一样。 isNaN(undefined)返回true,但undefined == undefined也为true。除null外,所有其他非数字类型也是如此。

–安迪
2015年9月1日下午16:41

换句话说,值!==值可能是测试值是否真正为NaN的最短方法。

–安迪
2015年9月1日下午16:43

看起来你是对的,@ Andy。现在,这很特殊。

– Alsciende
2015年9月2日,9:55

短语“这些值可能不相同”没有意义,因为这些值不存在。

–德米特里·扎伊采夫(Dmitri Zaitsev)
16年5月29日在18:15

#2 楼

好吧,一个叫做“非数字”的东西被认为是数字似乎有点奇怪,但是NaN仍然是数字类型,尽管事实:-)
NaN只是意味着不能在数字类型的局限性(尽管可以对所有必须四舍五入的数字说,但NaN是一种特殊情况)。
一个特定的NaN不被认为等于另一个NaN,因为它们可能是不同的值。但是,NaN仍然是数字类型,就像2718或31415一样。

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

与NaN的比较总是返回一个即使与自身进行比较也无法获得无序结果。比较谓词是信令通知或非信令通知,信令版本表示此类比较的无效异常。等式和不等式谓词是无信号的,因此x = x返回false可以用来测试x是否是安静的NaN。

所有这些都是(分解为多个部分):

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

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

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

尝试进行比较(小于,大于等NaN与另一个数字之间的on运算可能会导致引发异常(发出信号),或者导致结果只是错误(非发出信号或安静)。

相等和不相等谓词是非-signalling,因此x = x返回false可以用来测试x是否是安静的NaN。

相等性测试(等于,不等于)从不发信号,因此使用它们不会引起异常。如果您使用常规数字x,则x == x将始终为true。如果xNaN,则x == x将始终为false。它使您可以轻松(安静地)检测NaN

评论


很好的解释,尽管我在最后两句话中有不同意见:检查x是否为NaN的更好方法是使用isNaN()函数

–卡洛斯·巴塞罗那
2013年8月9日13:50



@DominicRodger这是我的想法:typeof = =='数字'表示“ a作为IEEE 754浮点数在内部存储”

–安迪
2015年9月1日下午16:47

如果可以用不同的值(1.0 / 0.0或2.0 / 0.0)产生无限,为什么无限===无限返回true?

–哈希姆·科拉米(Hashem Qolami)
16年5月22日在9:15



@Hashem,很有可能是因为它们被视为相同的无穷大。将除法视为重复减法,无论您是从2还是1开始都没有区别,达到零(或更准确地说,没有达到)所需的步数相同。我了解数学大师确实具有不同的无穷大类别,但(1)我怀疑1/0和2/0处于同一类别,并且(2)IEEE754中只有一类无穷大(当然不是+/-)。

– paxdiablo
16年5月22日在11:02



我不知道以任何有意义的方式来定义这些例外的“实际数字”。在数学中,对数和负数的根只能通过将实数扩展为复数来获得,在复数中它们求和为多个值,并且0/0并未以任何有意义的方式定义,除了说其“值”是整个数字集。即使定义了它们,Math.log(-1)== Math.log(-1)的结果仍为false。因此,除了NaN之外,没有其他“实际数字”,即使有,也没有用于比较。

–德米特里·扎伊采夫(Dmitri Zaitsev)
16年5月31日在13:05



#3 楼

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在Wikipedia上

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

该标准定义了<算术格式:二进制和十进制浮点数据集,由有限数字(包括带符号的零和次正规数),无穷大和特殊的“非数字”组成“值(NaNs)




#4 楼

typeof NaN返回'number'的原因是:




ECMAScript规范说Number类型包括NaN:


4.3.20 Number类型

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



/>因此typeof相应地返回:


11.4.3运算符的类型

产生UnaryExpression:typeof UnaryExpression的求值如下:
/>

让val为评估UnaryExpression的结果。
如果Type(val)为Reference,则

如果IsUnresolvableReference(val)为true,则返回"undefined"
让val为GetValue(val)。


返回根据表20由Type(val)确定的字符串。




                 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数字类型

Number类型正好具有18437736874454810627(即253−264 + 3)值,表示双精度64位格式IEEE 754
值,如IEEE二进制浮点标准运算法则,只是用
ECMAScript表示9007199254740990(即253-2)不同的IEEE标准的“非数字”值。作为单个特殊的NaN值。 (请注意,NaN值
由程序表达式NaN产生。)


#5 楼

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

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

评论


抱歉,但我不得不说这不是考虑的好方法。 “不一定是相同的非数字”并不意味着它们总是不同的,比较它们应得出错误的结果。最好不要量化NaN,而只是将其视为我们知识库中的一个奇怪现象。

–戴夫
2011-12-10 3:13

那么,为什么所有的Infinity都一样?有什么想法吗?

–哈希姆·科拉米(Hashem Qolami)
16年5月22日在9:17

#6 楼

NaN != NaN因为它们不是必需的SAME非编号。因此,这很有意义...
为什么浮点数的+0.00和-0.00都不一样。四舍五入可能会使它们实际上不为零。

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

评论


嗯,请考虑:var x = parseInt('no dice'),y = x;现在我要说两个NaN完全一样吗?但是不,x === y也返回false。

– KooiInc
2010年5月10日,9:38

是的,但是您不能确定,因此它们并不相同。它与数据库中的NULLable逻辑相同。尽管许多人认为它们与其他编程语言的空指针相同,但实际上它们具有完全不同的语义。它们是“未知”,因此一个NULL值与另一个NULL值始终为false。对NULL值进行计算最终会得到结果NULL。尝试从被称为UNKNOWN的值的角度查看它

–电影
2010年5月11日,下午1:39

作为数字类型,NaN是原始的,因此由其值唯一确定。

–德米特里·扎伊采夫(Dmitri Zaitsev)
16年5月17日在3:45

#7 楼

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

尽管其名称表明它不是数字,用于保存它的数据类型是数字类型。因此,在JavaScript中,询问NaN的数据类型将返回number(如alert(typeof(NaN))清楚地说明了)。

评论


实际除以零会计算为Infinity而非NaN

–德米特里·扎伊采夫(Dmitri Zaitsev)
16年5月29日在18:26

#8 楼

Javascript使用NaN表示遇到的任何内容,而规范无法用其他方式来表示。这并不意味着它不是数字。这是描述相遇的最简单方法。 NaN表示javascript不能以任何其他方式表示它或引用它的对象。实际上,它是“未知的”。作为“未知”,它无法告诉您它是什么,即使它本身也是。它甚至不是分配给它的对象。它只能告诉您什么不是,而虚无只能用一种编程语言来数学描述。由于数学是关于数字的,因此javascript将虚无表示为NaN。这并不意味着它不是数字。这意味着我们无法以其他任何有意义的方式阅读它。这就是为什么它甚至不能等同于自身的原因。因为不是。

#9 楼

NaN的一个更好的名字是数字上的例外,它可以更精确,更容易地描述其含义。实际上,这是另一种伪装成具有原始类型的异常对象(通过语言设计),在这种情况下,在其错误的自比较中,该异常对象不被视为原始类型。造成混乱的地方。只要语言“不会决定”在适当的异常对象和原始数字之间进行选择,混乱就将一直存在。

NaN本身臭名昭著的不等式,即=====是令人困惑的设计的体现,该设计迫使此异常对象成为原始类型。这打破了基本原则,即基本要素由其价值唯一确定。如果优先将NaN视为例外(可以有不同的种类),则不应将其作为原始出售。如果希望它是原始的,则必须遵守该原则。只要它被破坏了(就像我们在JavaScript中一样),并且我们不能真正在两者之间做出决定,那么对于每个参与人员而言,导致不必要的认知负担的混乱将依然存在。但是,只需在两者之间进行选择就可以很容易地解决该问题:


要么使NaN成为一个特殊的异常对象,它包含有关异常发生的有用信息,而不是将该信息丢弃为当前实现的信息,导致难以调试的代码;或者将NaN设置为原始类型number的实体(可以更容易地将其称为“数字”),在这种情况下,应该等同于自身,不能包含任何其他信息;后者显然是次等选择。

强制将NaN转换为number类型的唯一可能的优势是能够将其返回任何数值表达式。但是,这使之成为易碎的选择,因为包含NaN的任何数值表达式的结果要么是NaN,要么导致不可预测的结果,例如NaN < 0求值为false,即返回boolean而不是保留异常。

即使“事物就是它们的样子”,也没有什么可以阻止我们为自己做出清楚的区分,以帮助使我们的代码更可预测且更易于调试。实际上,这意味着识别那些例外并将其作为例外处理。不幸的是,这意味着更多的代码,但希望可以通过诸如Flowtype的TypeScript之类的工具来减轻。

然后我们就获得了安静的qs和嘈杂的信号,即NaN的区别。这实际上是关于异常的处理方式,而不是异常本身,与其他异常没有什么不同。

类似地,Infinity+Infinity是在实线扩展中出现的数字类型的元素,但它们是不是实数。从数学上讲,它们可以由收敛到+-Infinity的实数序列表示。

#10 楼

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

评论


像其他所有对象一样,Number可以具有任何类型的属性。 Number.fu =“ bar”; alert(typeof Number.fu);

– Alsciende
2010年5月10日下午14:10

NaN不是存储在Number.NaN中的值,无论它是什么。 NaN是Number类型的原始值。另外,Number.NaN的值为NaN,但这无关紧要。

– Oriol
2015年1月10日在21:06



#11 楼

想到NAN的最好方法是它不是一个已知的数字。这就是为什么NA​​N!= NAN的原因,因为每个NAN值代表一个唯一的未知数。 NAN是必需的,因为浮点数的值范围有限。在某些情况下,舍入会在低位丢失的情况下发生,从而导致看起来像1.0 / 11 * 11!= 1.0这样的废话。真正大的值是无穷大的NAN,这是一个很好的例子。

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

评论


NaN不代表无穷大。尝试表示超出范围的数字将四舍五入(至max / -inf)或四舍五入(至min / + inf)。

–橙色狗
14年4月15日在9:25

#12 楼

因为NaN是数字数据类型。

#13 楼

从类型的角度来看,NaN是一个数字,但不是正常数字(例如1、2或329131)。名称“非数字”表示所代表的值是特殊的,并且与IEEE格式规范域有关,不是javascript语言域。

#14 楼

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

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


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

评论


谢啦。我在Typescript的util包中遇到了isNumber问题。很好,我们仍然在项目中使用jQuery,因此改用了您的建议。

– Ashok M A
17年11月16日在14:12

对于rec,来自typescript util的isNumber对于NaN也返回true。

– Ashok M A
17年11月16日在14:13

#15 楼

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

parseInt所做的全部就是将字符串“转换”为数字数据类型,因此结果始终为“ number”。仅当原始字符串不可解析时,其值为NaN。

#16 楼

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

#17 楼

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

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

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

#18 楼

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

http://wtfjs.com/page/13

如果您停止以逻辑方式解决这些怪异,则可以解释其中的大多数怪癖,或者如果您对数论有所了解,但是如果您对数论不了解,它们仍然可以吸引您。

我建议阅读http:// wtfjs的其余部分.com /-比这更有趣的怪癖!

#19 楼

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

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

评论


从什么意义上说,它是“价值”? NaN == Number.NaN计算为false!

–德米特里·扎伊采夫(Dmitri Zaitsev)
16年5月17日在3:47

@DmitriZaitsev您读过主题吗?并且您是否尝试过(parseInt(“ nan”)== Number.NaN)?还可以尝试!=并查看其内容。

–Rob
16年5月17日在13:58

抱歉,忘记了愚蠢的NaN == NaN是错误的,一定是一个虐待狂发明了使每个人受苦的那个人。

–德米特里·扎伊采夫(Dmitri Zaitsev)
16年5月17日在14:53

#20 楼

一个例子

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

Number("string"); // returns NaN


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

评论


您似乎错过了问题的重点。 NaN是数字类型。问题是为什么。

–昆汀
19-4-10在14:28



@Quentin我在最后一行解释了。

– Amir Fo
19年4月10日在14:29

#21 楼

Number类型的特殊值是POSITIVE_INFINITY

为什么?通过设计