所以我决定尝试通过编写一些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来做到这一点,但我只是想知道是否有办法用十进制模块来解决这个问题。
有帮助吗?

解决方案

将十进制工作精度更改为2位是一个好主意,除非您绝对只打算执行单个操作。

您应始终以高于重要性水平的精度执行计算,并且仅围绕最终结果。如果执行长序列计算并四舍五入到每一步的有效位数,则会累积错误。十进制模块不知道任何特定操作是长序列中的一个还是最终结果,因此它假定它不应该超过必要的舍入。理想情况下它会使用无限精度,但这太昂贵了,所以Python开发人员确定了28位数。

一旦你到达最终结果,你可能想要的是量化:

>>> (Decimal('1.00') / Decimal('3.00')).quantize(Decimal("0.001"))
Decimal("0.333")

您必须手动跟踪重要性。如果要进行自动重要性跟踪,则应使用区间运算。有一些可用于Python的库,包括 pyinterval mpmath (支持任意精度)。使用十进制库实现区间运算也很简单,因为它支持有向舍入。

您可能还想阅读十进制算术常见问题:十进制算术‘意义& #8217;算术?

其他提示

小数不会丢弃这样的小数位数。如果你真的想将精度限制在2 d.p.然后尝试

decimal.getcontext().prec=2

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

出于好奇......是否有必要使用十进制模块?当你准备好看到它们时,为什么浮点数没有重要的数字四舍五入?或者您是否正在尝试跟踪计算的重要数据(例如,当您必须对结果进行错误分析时,计算计算误差是计算中不确定性的函数)?如果你想要一个从数字左边而不是右边舍入的舍入函数,请尝试:

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

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

如果我正确地进行了Decimal,那么“精确度”就是“精确”。是十进制表示法中小数点后的位数。

您似乎想要别的东西:有效位数。这比科学记数法中小数点后的位数多一个。

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

浮点有什么问题?

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

它专为具有有限位数的科学式计算而设计。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top