Python浮点复制问题

时间:2010-03-26 16:40:03

标签: python floating-point variable-assignment

我对复制浮点数组成员时遇到的一些行为感到困惑 另一个变量 - 请帮助!

例如

data_entry[1] = 9.6850069951

new_value = data_entry[1]


<comment> #print both

9.6850069951


9.6850663300

我知道浮子的二进制存储问题,但我想 如果直接复制内存,我们最终会得到相同的值。

有什么想法吗?我需要比这更精确! 提前致谢 斯图尔特

5 个答案:

答案 0 :(得分:4)

赋值后,变量new_value不是float的副本,它只是对完全相同对象的另一个引用。因此,它不可能具有不同的印刷表示。所以在原始问题中肯定省略了一些细节。

Stuart - 您能否请尝试以下内容并发布结果,或告诉我们您的实际代码如何变化。请注意,new_value data_entry [1],即它们都是同一个对象。

>> data_entry = [0,0]
>> data_entry[1] = 9.6850069951
>> new_value = data_entry[1]
>> new_value is data_entry[1]
True
>> print data_entry[1], new_value
9.6850069951 9.6850069951

答案 1 :(得分:3)

如果您真的使用array模块(或numpy的数组),则很容易解释精度损失,例如:

>>> dataentry = array.array('f', [9.6850069951])
>>> dataentry[0]
9.6850070953369141

这里,'f'第一个arg到array.array说我们正在使用32位浮点数,所以只有大约7个有效数字“存活”。但是使用64位浮点数很容易(曾经一度被称为“双精度”!):

>>> dataentry = array.array('d', [9.6850069951])
>>> dataentry[0]
9.6850069951000002

正如你所看到的,这种方式超过了十几个有效数字“存活”(你通常可以依赖大约14+,除非你做算术“oops”,比如把数字的差异非常接近,当然吞噬你的精确度; - )。

答案 2 :(得分:0)

在Linux上使用Python 2.6.2不适用于我:

>>> data_entry = [1, 2]
>>> data_entry[1] = 9.6850069951
>>> new_value = data_entry[1]
>>> print data_entry[1]
--> print(data_entry[1])
9.6850069951
>>> print new_value
--> print(new_value)
9.6850069951

一种选择是切换到使用Decimal对象:

>>> from decimal import Decimal
>>> data_entry[1] = Decimal('9.6850069951')
>>> new_value = data_entry[1]
>>> print data_entry[1]
--> print(data_entry[1])
9.6850069951
>>> print new_value
--> print(new_value)
9.6850069951

如果你以某种方式失去精确度,这可能会有所帮助。

答案 3 :(得分:0)

你已经离开了一些代码。

>>> data_entry=[0,0]
>>> data_entry[1] = 9.6850069951
>>> 
>>> new_value = data_entry[1]
>>> print data_entry
[0, 9.6850069951000002]
>>> print new_value
9.6850069951
>>> print data_entry[1]
9.6850069951

此浮点数的reprstr产生不同的结果。我的猜测是你发布的代码省略了这个差异。

答案 4 :(得分:0)

以下是一些格式化的编辑代码:

old code:
data = []
for data_entry in data:
    if (data_entry[1] != 0):
    value = data_entry[1]
    modlog(logging.INFO,'raw value = %.12f',data_entry[1])
    modlog(logging.INFO,'value_in = %.12f', value)
output:
:INFO:raw value = 2.334650748292
:INFO:value_in  = 2.334685585881

new code:
data = array.array('d') 
if (data[index] != 0):
    test_data = data[index]
    modlog(logging.INFO,'raw data = %.12f', data[(index)])
    modlog(logging.INFO,'test_data = %.12f', test_data)
output:
:INFO:raw data = 2.333840588874
:INFO:test_data= 2.333840588874