早上好,
我正在读取FITS文件中的两个数字(表示单个数字的整数和浮点部分),将它们转换为长双精度数(我机器中的128位),然后将它们相加。
结果不像我期望的那样使用128位浮点数。这是代码:
a_int = np.longdouble(read_header_key(fits_file, 'I'))
print "I %.25f" % a_int, type(a_int)
a_float = np.longdouble(read_header_key(fits_file, 'F'))
print "F %.25f" % a_float, a_float.dtype
a = a_int + a_float
print "TOT %.25f" % a, a.dtype
这是我得到的答案:
I 55197.0000000000000000000000000 <type 'numpy.float128'>
F 0.0007660185200000000195833 float128
TOT 55197.0007660185219720005989075 float128
结果与我预期的结果不符(55197.0007660185200000000195833)仅为11位小数(总共16位有效数字)。我期望从128位浮点数获得更好的精度。我究竟做错了什么?
此结果在Mac机器和Linux 32位机器上重现(在这种情况下,dtype是float96,但值完全相同)
提前感谢您的帮助!
利玛
答案 0 :(得分:3)
我的猜测是%f
修饰符从你的longdouble对象构造一个float,并在创建格式字符串时使用它。
>>> import numpy as np
>>> np.longdouble(55197)
55197.0
>>> a = np.longdouble(55197)
>>> b = np.longdouble(0.0007660185200000000195833)
>>> a
55197.0
>>> b
0.00076601852000000001958
>>> a + b
55197.00076601852
>>> type(a+b)
<type 'numpy.float128'>
>>> a + b == 55197.00076601852
False
作为旁注,即使repr
也没有打印足够的digets来重建对象。这只是因为你不能拥有一个足以传递给longdouble
的浮点文字。
答案 1 :(得分:3)
问题在于您打印np.longdouble
。使用%f
格式化时,Python会在打印前将结果转换为浮点数(64位)。
下面:
>>> a_int = np.longdouble(55197)
>>> a_float = np.longdouble(76601852) / 10**11
>>> b = a_int + a_float
>>> '%.25f' % b
'55197.0007660185219720005989075'
>>> '%.25f' % float(b)
'55197.0007660185219720005989075'
>>> b * 10**18
5.5197000766018519998e+22
请注意,在我的机器上,longdouble
与普通double
相比,我只能获得更高的精度(20位小数而不是15位)。因此,可能值得看看Decimal
模块是否更适合您的应用程序。 Decimal
处理任意精度的十进制浮点数而不会损失精度。