为啥从字符串转换的python浮点数与相同值的普通浮点数不同? [复制]
Posted
技术标签:
【中文标题】为啥从字符串转换的python浮点数与相同值的普通浮点数不同? [复制]【英文标题】:Why is a python float which was converted from a string not the same as a normal float of the same value? [duplicate]为什么从字符串转换的python浮点数与相同值的普通浮点数不同? [复制] 【发布时间】:2018-11-30 12:56:43 【问题描述】:我在 Python 3.6.5 中遇到了一个奇怪的现象:float('50.0')
与 float(50.0)
不一样,尽管它们彼此相等。
我运行了一些代码来找出不同之处。除了python说它们不一样,我找不到区别。我很困惑。如果有人能解释这里发生的事情,我会很高兴。
这是我的测试:
if float('50.0') is float(50.0):
print("float('50.0') is float(50.0)")
else:
print("float('50.0') is not float(50.0)")
if float('50.0') == float(50.0):
print("float('50.0') == float(50.0)")
else:
print("float('50.0') != float(50.0)")
if float('50.0') is 50.0:
print("float('50.0') is 50.0")
else:
print("float('50.0') is not 50.0")
if float(50.0) is 50.0:
print('float(50.0) is 50.0')
else:
print('float(50.0) is not 50.0')
if float(50.0) is float(50.0):
print('float(50.0) is float(50.0)')
else:
print('float(50.0) is not float(50.0)')
xstr_float = float('50.0')
norm_float = float(50.0)
print ('xstr_float: 0:.100f'.format(xstr_float))
print ('xstr_float is of type:'.format(type(xstr_float)))
print ('norm_float: 0:.100f'.format(norm_float))
print ('norm_float is of type:'.format(type(norm_float)))
和我的结果:
float('50.0') is not float(50.0)
float('50.0') == float(50.0)
float('50.0') is not 50.0
float(50.0) is 50.0
float(50.0) is float(50.0)
xstr_float: 50.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
xstr_float is of type:<class 'float'>
norm_float: 50.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
norm_float is of type:<class 'float'>
根据 cmets 中的一些讨论,我尝试了以下方法,得到的结果无法回答问题:
x = float(50.0)
y = float(50.0)
if x is y:
print('x is y')
else:
print('x is not y')
x=12345
y=12345
if x is y:
print('x is y')
else:
print('x is not y')
结果:
x is y
x is y
更新:我已经标记了一个正确的答案,并且根据对该答案的评论,我想向其他可能感到困惑的人展示我错过了什么:
当python创建一个对象时,它被分配了一个ID。 is
在比较两个对象返回相同 ID 时返回 true。有时python会缓存和重用一个对象。所以在x is y
的情况下,我们可以看到一个对象被给定并被重用,因为ID是相同的。我们还看到 python 会话之间的 ID 发生了变化:
x=12345
y=12345
if x is y:
print('x is y')
else:
print('x is not y')
print('x_id: '.format(id(x)))
print('y_id: '.format(id(y)))
结果
x is y
x_id: 2476500365040
y_id: 2476500365040
在下一次运行时它会导致
x is y
x_id: 2234418638576
y_id: 2234418638576
如果由于某种原因不能重用同一个对象来表示 x 和 y,那么 x is y
将返回 false。
【问题讨论】:
不要与is
比较值,使用==
。
@DanielRoseman 很明显他在比较价值和身份,这就是为什么同时使用 is
和 ==
的原因
但是为什么他会期望不同的对象有相同的身份呢?
观察:x=12345; y=12345; (x is y) == False
这与浮动的制作方式无关。
所以为了清楚地说明这一点,您了解==
和is
之间的区别,并且您在问为什么CPython 有时会重复使用相同的浮点实例而有时不会?
【参考方案1】:
我想你可能会对一开始也让我感到困惑的事情感到困惑。 is
与 ==
不同。
如果两个变量指向同一个对象,is
将返回 True
。
如果变量指向相等的对象,==
将返回 True
。
帮助我理解这一点的答案在这个问题下:
Is there a difference between ==
and is
in Python?
【讨论】:
啊。您链接到的问题在帮助我理解方面做得很好。谢谢!所以在这些情况下,一定是python是“cach[ing] small integer objects,这是一个实现细节。对于较大的整数,这不起作用:” 补充一点理解。x is y
与 id(x) == id(y)
含义相同。
@user2653663 您的评论对完善这个想法非常有帮助。我更新了我的问题,以向有相同问题的人展示您的想法。以上是关于为啥从字符串转换的python浮点数与相同值的普通浮点数不同? [复制]的主要内容,如果未能解决你的问题,请参考以下文章