小数模块中的有效数字
因此,我决定尝试通过编写一些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位精度。
限制返回的位数的唯一方法是更改精度。
小数不会丢掉这样的小数位。如果我们真的想将精度限制为2 d.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")
我们必须手动跟踪重要性。如果要进行自动重要性跟踪,则应使用间隔算法。有一些适用于Python的库,包括pyinterval和mpmath(支持任意精度)。用十进制库实现区间算术也很简单,因为它支持定向舍入。
我们可能还需要阅读Decimal Arithmetic FAQ(十进制算术常见问题解答):十进制算术有效算术吗?
出于好奇...是否有必要使用小数模块?当我们准备好对数字进行四舍五入时,为什么不使用浮点数呢?还是我们要跟踪计算的重要数字(例如,当我们必须对结果进行误差分析时,根据所计算的不确定性来计算所计算的误差)?如果要使用从数字的左边而不是右边的舍入函数,请尝试:
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')