为啥从字符串转换的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 yid(x) == id(y) 含义相同。 @user2653663 您的评论对完善这个想法非常有帮助。我更新了我的问题,以向有相同问题的人展示您的想法。

以上是关于为啥从字符串转换的python浮点数与相同值的普通浮点数不同? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在python中将23位浮点数从字符串转换为浮点数并返回?

从字符串到浮点数与python中的argv

python课程设计笔记整数浮点数与字符串

无法在python中将字符串转换为浮点数

为啥 Python 3 字符串函数似乎会降低浮点数的精度?

为啥C++里面浮点与整数相乘的结果跟在计算器里的不一样呢?浮点我选的float