我对复制浮点数组成员时遇到的一些行为感到困惑 另一个变量 - 请帮助!
例如
data_entry[1] = 9.6850069951
new_value = data_entry[1]
<comment> #print both
9.6850069951
9.6850663300
我知道浮子的二进制存储问题,但我想 如果直接复制内存,我们最终会得到相同的值。
有什么想法吗?我需要比这更精确! 提前致谢 斯图尔特
答案 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
此浮点数的repr
和str
产生不同的结果。我的猜测是你发布的代码省略了这个差异。
答案 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