小数模块中的有效数字

发布于 2024-07-06 11:04:56 字数 509 浏览 8 评论 0原文

所以我决定尝试通过编写一些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 来做到这一点,但我只是想知道是否有一种方法可以出于好奇而使用十进制模块来做到这一点。

So I've decided to try to solve my physics homework by writing some python scripts to solve problems for me. One problem that I'm running into is that significant figures don't always seem to come out properly. For example this handles significant figures properly:

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

But this doesn't:

>>> Decimal('1.00') / Decimal('3.00')
Decimal("0.3333333333333333333333333333")

So two questions:

  1. Am I right that this isn't the expected amount of significant digits, or do I need to brush up on significant digit math?
  2. Is there any way to do this without having to set the decimal precision manually? Granted, I'm sure I can use numpy to do this, but I just want to know if there's a way to do this with the decimal module out of curiosity.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

梦萦几度 2024-07-13 11:04:56

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

您应始终以高于显着性水平的精度执行计算,并且仅对最终结果进行舍入。 如果执行一长串计算并在每一步四舍五入到有效位数,错误将会累积。 Decimal 模块不知道任何特定操作是否是长序列中的一个,也不知道最终结果,因此它假设它不应舍入超过必要的值。 理想情况下,它会使用无限精度,但这太昂贵,因此 Python 开发人员选择了 28 位数字。

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

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

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

您可能还想阅读十进制算术常见问题解答:十进制算术是“有效”算术吗?

Changing the decimal working precision to 2 digits is not a good idea, unless you absolutely only are going to perform a single operation.

You should always perform calculations at higher precision than the level of significance, and only round the final result. If you perform a long sequence of calculations and round to the number of significant digits at each step, errors will accumulate. The decimal module doesn't know whether any particular operation is one in a long sequence, or the final result, so it assumes that it shouldn't round more than necessary. Ideally it would use infinite precision, but that is too expensive so the Python developers settled for 28 digits.

Once you've arrived at the final result, what you probably want is quantize:

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

You have to keep track of significance manually. If you want automatic significance tracking, you should use interval arithmetic. There are some libraries available for Python, including pyinterval and mpmath (which supports arbitrary precision). It is also straightforward to implement interval arithmetic with the decimal library, since it supports directed rounding.

You may also want to read the Decimal Arithmetic FAQ: Is the decimal arithmetic ‘significance’ arithmetic?

献世佛 2024-07-13 11:04:56

小数不会像这样丢弃小数位。 如果您确实想将精度限制为 2 dp,请尝试

decimal.getcontext().prec=2

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

Decimals won't throw away decimal places like that. If you really want to limit precision to 2 d.p. then try

decimal.getcontext().prec=2

EDIT: You can alternatively call quantize() every time you multiply or divide (addition and subtraction will preserve the 2 dps).

心的位置 2024-07-13 11:04:56

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

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

Just out of curiosity...is it necessary to use the decimal module? Why not floating point with a significant-figures rounding of numbers when you are ready to see them? Or are you trying to keep track of the significant figures of the computation (like when you have to do an error analysis of a result, calculating the computed error as a function of the uncertainties that went into the calculation)? If you want a rounding function that rounds from the left of the number instead of the right, try:

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  

The numbers will look right when you print them or convert them to strings, but if you are working at the prompt and don't explicitly print them they may look a bit strange:

>>> lround(1./3.,2),str(lround(1./3.,2)),str(lround(1./3.,4))
(0.33000000000000002, '0.33', '0.3333')
彻夜缠绵 2024-07-13 11:04:56

小数默认为 28 位精度。
限制它返回的位数的唯一方法是改变精度。

Decimal defaults to 28 places of precision.
The only way to limit the number of digits it returns is by altering the precision.

寄居者 2024-07-13 11:04:56

浮点数有什么问题?

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

它是为有效数字有限的科学式计算而设计的。

What's wrong with floating point?

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

It was designed for scientific-style calculations with a limited number of significant digits.

念﹏祤嫣 2024-07-13 11:04:56

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

您似乎想要其他东西:有效数字的数量。 这比科学计数法中小数点后的位数多一位。

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

If I undertand Decimal correctly, the "precision" is the number of digits after the decimal point in decimal notation.

You seem to want something else: the number of significant digits. That is one more than the number of digits after the decimal point in scientific notation.

I would be interested in learning about a Python module that does significant-digits-aware floating point point computations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文