Python 十进制模块中的有效数字

Python 十进制模块中的有效数字,python,floating-point,decimal,physics,significance,Python,Floating Point,Decimal,Physics,Significance,所以我决定写一些python脚本来帮我解决问题,以此来解决我的物理作业。我遇到的一个问题是,重要的数字似乎并不总是正确地显示出来。例如,这将正确处理有效数字: from decimal import Decimal >>> Decimal('1.0') + Decimal('2.0') Decimal("3.0") 但这并不是: >>> Decimal('1.00') / Decimal('3.00') Decimal("0.3333333333333333

所以我决定写一些python脚本来帮我解决问题,以此来解决我的物理作业。我遇到的一个问题是,重要的数字似乎并不总是正确地显示出来。例如,这将正确处理有效数字:

from decimal import Decimal
>>> Decimal('1.0') + Decimal('2.0')
Decimal("3.0")
但这并不是:

>>> Decimal('1.00') / Decimal('3.00')
Decimal("0.3333333333333333333333333333")
所以有两个问题:

  • 这不是有效数字的预期数量,或者我需要复习有效数字的数学吗
  • 有没有办法不用手动设置十进制精度就可以做到这一点?当然,我确信我可以使用numpy来实现这一点,但出于好奇,我只想知道是否有一种方法可以使用十进制模块实现这一点

  • 十进制默认为28位精度。

    限制它返回的位数的唯一方法是改变精度。

    小数不会像那样丢掉小数位数。如果你真的想把精度限制在2d.p.那么试试吧

    decimal.getcontext().prec=2
    

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

    如果我正确理解十进制,“精度”是十进制记数法中小数点后的位数

    您似乎还需要其他东西:有效位数。这比科学记数法中小数点后的位数多一位


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

    浮点有什么问题

    >>> "%8.2e"%  ( 1.0/3.0 )
    '3.33e-01'
    

    它是为科学风格的计算而设计的,有效位数有限。

    将十进制工作精度更改为2位数不是一个好主意,除非您完全只执行一个操作

    您应该始终以高于显著性级别的精度执行计算,并且只对最终结果进行四舍五入。如果执行一长串计算并在每一步四舍五入到有效位数,则错误将累积。十进制模块不知道任何特定的操作是长序列中的一个操作,还是最终结果,因此它假设它不应该舍入得太多。理想情况下,它将使用无限精度,但这太昂贵了,因此Python开发人员决定使用28位数字

    一旦得出最终结果,您可能需要的是量化:

    >>> (Decimal('1.00') / Decimal('3.00')).quantize(Decimal("0.001")) Decimal("0.333") >>>(十进制('1.00')/十进制('3.00'))。量化(十进制('0.001')) 十进制(“0.333”) 您必须手动跟踪重要性。如果想要自动跟踪重要性,应该使用区间算法。Python有一些可用的库,包括和(支持任意精度)。使用十进制库实现区间算术也很简单,因为它支持定向舍入


    出于好奇,您可能还想阅读

    ,是否需要使用十进制模块?当您准备好查看数字时,为什么不使用有效数字四舍五入的浮点呢?或者,您是否试图跟踪计算的有效数字(例如,当您必须对结果进行误差分析时,将计算出的误差计算为计算中不确定性的函数)?如果需要从数字的左侧而不是右侧取整的取整函数,请尝试:

    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')
    

    这不一定总是正确的。例如:>>>Decimal('1.0')*Decimal('1.0')产生Decimal('1.00')您可能是在除法的上下文中这样说的吗?嗯。。。因此,如果不要求我手动设置精度,就无法让它这样做?问题是,我仍然会手动设置有效数字的数量。我确实看不出设置有效数字有什么问题。你必须展开你的问题,以显示你想要什么以及为什么你不能/不想设置有效数字。300/100怎么样?您的代码将导致错误的结果为3.000