比较“float('nan')”和“数学.nan"

2024-04-26 21:52:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个浮点变量,它可能是一个数字,也可能不是一个数字,我想检查一下是否是这样。使用x = float('nan'),我观察到一些让我吃惊的行为:

    print(x is math.nan)
^{pr2}$

这意味着float('nan')和{}是不同的对象,这是我没有料到的,但这没关系。但是,当我检查与==是否相等时,结果是相同的:

print(x == math.nan):
^{pr2}$

如果我使用math.isnan(x),那么所有类型的非a-number都会得到正确的结果。但是,为什么float('nan') == math.nan的计算结果不为True?。


Tags: 对象true类型numberis数字mathnan
3条回答

“不是数字”是(在某种意义上)没有值。在

传统上,根据IEEE浮点规范,它本身并不等于。在

那是因为没有有意义的价值可以比较。在

实际上,some people use this fact to detect NaN,所以您可以尝试使用x != x作为您的条件(尽管链接的Q&A可以说有一些更好的建议)。在

但是,表达式math.nan is math.nan是真的,因为is执行的是对象标识比较,而不是值等价/相等比较。在

这是因为NaN只是一个浮点值。使用is不检查变量是否具有相同的值,而是检查它们是否是相同的对象。如果创建具有相同值的两个浮点,则它们不是同一个对象,而是具有相同值的两个对象。以这个为例:

>>> a = float('nan')
>>> b = float('nan')
>>> a is b
False

因此,即使以相同的方式创建两个NaN值,它们也不是同一个对象。即使对于更琐碎的浮动也是如此。试试这个:

^{pr2}$

Python的默认版本重用一些值,因此该值的任何实例都是同一个对象。以这个为例(注意没有十进制,这些是整数而不是浮点):

>>> a = 1
>>> b = 1
>>> a is b
True

但这是一个您永远不应该依赖的实现细节,它可以随时更改,并且可以随python实现而变化。但是即使这样,NaN也不是默认Python解释器执行此操作的值之一。在

您可以使用id函数手动检查两个变量是否是同一个对象,该函数为每个同时存在的对象提供一个唯一的编号(尽管如果删除了某个变量,即使是自动删除,这些数字也可以重复使用)。在

>>> a=1.
>>> b=1.
>>> c=float('nan')
>>> d=float('nan')
>>> e=1
>>> f=1
>>> id(a)
139622774035752
>>> id(b)
139622774035872
>>> id(c)
139622774035824
>>> id(d)
139622774035800
>>> id(e)
139622781650528
>>> id(f)
139622781650528

至于为什么它们不相等,这只是现代计算机上使用的NaN定义的一部分。根据定义,NaN永远不能等于自身。它是关于浮点数如何工作的国际标准的一部分,这种行为被构建到现代CPU中。在

这不是特殊行为:is返回两个对象是否实际引用同一个对象(本质上是在内存中),而==返回两个对象是否具有相同的值。在

要查看它们是否引用相同的内容,我们可以使用id()。在

>>> a = [1,2,3]
>>> b = a
>>> id(a)
140302781856200
>>> id(b)
140302781856200
>>> a == b
True
>>> a is b
True
>>> c = [1,2,3]
>>> id(c)
140302781864904
>>> a == c
True
>>> a is c
False

这里我们看到,通过赋值b = a,它们现在引用了同一个列表:因此is和{}是{}。然而,当我们将c定义为与ab相同值的新变量时,它是==,但是is返回{}。在

{14.14}也一样

相关问题 更多 >