十进制模块中的有效数字

5

我决定尝试通过编写一些Python脚本来解决我的物理作业。但我遇到的一个问题是,有效数字似乎并不总是正确。例如,下面这个例子可以正确处理有效数字:

from decimal import Decimal
>>> Decimal('1.0') + Decimal('2.0')
Decimal("3.0")

但这个不行:
>>> Decimal('1.00') / Decimal('3.00')
Decimal("0.3333333333333333333333333333")

所以有两个问题:

  1. 我是否正确,这不是期望的有效数字数量,还是我需要重新学习有效数字数学?
  2. 是否有任何方法可以在没有手动设置小数精度的情况下完成此操作? 道听途说,我确定可以使用numpy完成此操作,但我只想知道是否可以使用十进制模块完成此操作。
6个回答

8
将十进制工作精度更改为2位小数并不是一个好主意,除非您绝对只执行单个操作。
您应该始终以高于有效数字级别的精度执行计算,并仅舍入最终结果。如果您执行一系列长时间的计算并在每个步骤中四舍五入到有效数字个数,则会累积误差。十进制模块不知道任何特定操作是否是长序列中的一个操作还是最终结果,因此它假设不应该超过必要的舍入。理想情况下,它将使用无限精度,但这太昂贵了,因此Python开发人员选择了28个数字。
一旦您到达最终结果,您可能想要的是量化:
你需要手动跟踪重要性。如果想要自动跟踪重要性,应使用区间算术。Python有一些可用的库,包括pyintervalmpmath(支持任意精度)。还可以使用十进制库实现区间算术,因为它支持定向舍入。
你可能还想阅读十进制算术FAQ:十进制算术是否是“重要性”算术?

300/100怎么办?你的代码会错误地得出3.000。 - Pyrolistical

3

小数不会像那样舍去小数位。如果您确实想将精度限制为两位小数,请尝试:

decimal.getcontext().prec=2

编辑:您也可以选择在每次乘法或除法(加法和减法将保留2个小数位)时调用quantize()。


嗯...所以没有办法让它自动完成,而不需要我手动设置精度吗? - Jason Baker

1

只是出于好奇...使用十进制模块是必要的吗?当你准备看到它们时,为什么不使用浮点数并对数字进行有效数字舍入?或者你是在试图跟踪计算的有效数字(例如当你必须对结果进行误差分析时,计算作为计算中涉及的不确定性函数的计算误差)?如果你想要一个从数字左侧而不是右侧进行舍入的舍入函数,请尝试:

def lround(x,leadingDigits=0): 
    """Return x either as 'print' would show it (the default) 
    or rounded to the specified digit as counted from the leftmost 
    non-zero digit of the number, e.g. lround(0.00326,2) --> 0.0033
    """ 
    assert leadingDigits>=0 
    if leadingDigits==0: 
            return float(str(x)) #just give it back like 'print' would give it
    return float('%.*e' % (int(leadingDigits),x)) #give it back as rounded by the %e format  

数字在打印或转换为字符串时看起来是正确的,但如果您正在提示符处工作并且没有明确地打印它们,它们可能看起来有点奇怪:

>>> lround(1./3.,2),str(lround(1./3.,2)),str(lround(1./3.,4))
(0.33000000000000002, '0.33', '0.3333')

0

十进制默认精度为28位。
限制返回的数字位数的唯一方法是通过改变精度。


这并不总是正确的。例如:>>> Decimal('1.0') * Decimal('1.0') 会得到 Decimal("1.00")。你是不是在讨论除法的情况? - Jason Baker

0
浮点数有什么问题吗?
>>> "%8.2e"%  ( 1.0/3.0 )
'3.33e-01'

它被设计用于具有有限数量有效数字的科学计算。


问题在于我仍需手动设置有效数字的位数。 - Jason Baker
我确实不明白设置有效数字有什么问题。您需要扩展您的问题,以显示您想要什么以及为什么您不能/不想设置有效数字。 - S.Lott

-1

如果我正确理解十进制,"精度"是小数点后的数字数量,以十进制表示法为准。

您似乎想要另外一件事:有效数字的数量。这比科学计数法中小数点后的数字多一个。

我很想了解一个Python模块,它可以进行有效数字感知的浮点运算。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接