考虑以下代码(Windows 10上MSYS2中MINGW64上的Python 3.8.0):
import numpy as np
from decimal import Decimal
aa = [25744,25687,25641,25601,25566,25533,25505,25479,25456,25435]
npaa = np.array(aa)
print(np.mean(npaa)) # 25564.7
print(0.001*np.mean(npaa)) # 25.564700000000002
print( Decimal(np.mean(npaa)) ) # 25564.70000000000072759576141834259033203125
print( Decimal(0.001)*Decimal(np.mean(npaa)) ) # 25.56470000000000125976798437
因此,上述整数列表的平均值首先打印为25564.7,这是我期望并希望获得的结果。
但是,当我将此数字乘以0.0001时,我得到一吨的小数,这可能是由于float(im)精度造成的。
所以,我想-哎呀,我要使用Decimal类,在这种情况下,我应该得到“正确的”小数位数。
但是,一旦我尝试Decimal(np.mean(npaa))
,我就会得到一小数的平均值:25564.70000000000072759576141834259033203125
显然,np.mean(npaa)
已经包含了这些小数-但由于某些原因,它们没有被打印。
这就是问题-因为列表中我所有的都是整数,并且列表中有10个整数,在数学上(在这种情况下)我不可能得到任何其他结果,只有一个小数点后一位的数字,和仅1个小数。
现在,我可以通过将均值打印为字符串并将其格式设置为1个十进制形式(如"{:.1f}".format(np.mean(npaa))
)来解决此问题,然后将该字符串用作十进制来源-并且可以正常工作;但是然后,我有其他长度不为10的数组,我希望最小的小数位数自动出现在变量中-无需我手动找出我应该期望的小数位数,然后格式化它们作为字符串。
因此,我可以尝试使用一个十进制数组(如链接文章所试图做的那样),这并不简单:
print( np.array(aa,dtype=Decimal) ) # [25744 25687 25641 25601 25566 25533 25505 25479 25456 25435]
print( np.array(aa).astype(Decimal) ) # [25744 25687 25641 25601 25566 25533 25505 25479 25456 25435]
print( np.array([Decimal(ax) for ax in aa]) ) # [Decimal('25744') Decimal('25687') Decimal('25641') Decimal('25601') Decimal('25566') Decimal('25533') Decimal('25505') Decimal('25479') Decimal('25456') Decimal('25435')]
print( np.mean( np.array([Decimal(ax) for ax in aa]) ) ) # 25564.7
print( type(np.mean( np.array([Decimal(ax) for ax in aa]) )) ) # <class 'decimal.Decimal'>
print( Decimal(0.001)*np.mean( np.array([Decimal(ax) for ax in aa]) ) ) # 25.56470000000000053217222296
...,但是 even ,如果我现在有Decimal
为25564.7,乘以Decimal
为0.001(在Decimal
域中) ! -我 still 得到25.56470000000000053217222296!?
我该如何让Python将0.001 * 25564.7计算为25.5647,这就是应该的样子-无需“强制转换”,即将十进制/浮点值打印为字符串,并带有有限的小数位数? Decimal类是否应该能够做到这一点?
编辑:所以,我也尝试了sum()/len()
的方法,就像链接的文章一样-我最初以为是这样做的,但是没有:
print( sum(aa)/len(aa) ) # 25564.7
print( 0.001*sum(aa)/len(aa) ) # 25.5647
print( Decimal(0.001*sum(aa)/len(aa)) ) # 25.564699999999998425437297555617988109588623046875
print( sum(npaa)/len(npaa) ) # 25564.7
print( 0.001*sum(npaa)/len(npaa) ) # 25.5647
print( Decimal(0.001*sum(npaa)/len(npaa)) ) # 25.564699999999998425437297555617988109588623046875
https://docs.python.org/2/tutorial/floatingpoint.html
顺便说一句,十进制模块还提供了一种很好的方式来“查看”存储在任何特定Python浮点数中的确切值
https://docs.python.org/2/library/decimal.html
小数可以精确表示。相反,像
1.1
和2.2
这样的数字在二进制浮点数中没有确切的表示形式。最终用户通常不希望1.1 + 2.2
像二进制浮点一样显示为3.3000000000000003
。
因此,如果Decimal
数字可以精确表示,为什么在这种情况下使用Decimal
类时却得到相同的浮点不精确度?