繁体   English   中英

在 Python 中计算有效数字?

[英]Counting significant figures in Python?

Python中有没有办法计算双/浮点/等中的有效数字? 我没有看到一个简单的方法来做到这一点,但我希望它会在图书馆里。

提前致谢。

没有。重要的数字只是没什么大不了的,并且得不到计算机语言的支持。 进行实际计算的人需要误差棒,这些误差棒具有更高的精度 - 实际测量表明非常精确的事情,例如“这是0.11±0.03mm”而不是说不太精确的陈述“这是0.1毫米”或“这是0.11毫米” “即使你的不精确实际上并没有达到10的幂,你也会选择10的幂。

内置的Decimal 库可以很好地解决这个问题,因为它解决了使用基于硬件的浮点数的问题。 它有一个内部表示,只包含有效数字和指数。 所以你可以用它来计算这样的有效数字:

from decimal import Decimal
def count_sigfigs(numstr):
    return len(Decimal(numstr).normalize().as_tuple().digits)
 

这适用于很多例子,比如这些例子(来自这个相关问题)。 请注意,您必须将数字作为字符串输入才能正常工作。 由于它们的硬件表示,使用浮点数会搞砸。

tests = [('2', 1),
 ('1234', 4),
 ('2.34', 3),
 ('3000', 1),
 ('0.0034', 2),
 ('120.5e50', 4),
 ('1120.5e+50', 5),
 ('120.52e-50', 5)]

for num, expected in tests:
    print(count_sigfigs(num) == expected)

这使:

True
True
True
True
True
True
True
True

不幸的是,这不适用于像“1.000”这样有 4 个 sigfigs 的数字。 这只是给出 1。所以它需要改进以涵盖所有情况。 它也为“0”给出 1,尽管通常应该给出 0。

如果您取出normalize ,那么它适用于1.000但不适用于 3000(它说 4 而不是 1)。

您可能对任意精度浮点库感兴趣,例如:

http://code.google.com/p/mpmath/

我在另一个问题中找到了这篇文章的解决方案:

Python计算有效数字

这里的想法是你将float作为String传递给方法,然后该方法使用正则表达式通过分割字符串来计算有效数字的位数,其中"e"是(对于科学格式的浮点字符串)和点的位置是(对于普通的浮点字符串)。

它似乎可以很好地工作到8位有效数字,但在9日之后不能保证这种行为。

不过,我相信这比这更好

“重要的数字并不是那么大,在计算机语言中得不到什么支持”

响应。 这可能并不容易,但你绝对可以做到,即使不是很完美。

计算机根本不能以这种方式工作,至少,除非它们被编程为这样做。 假设你给他们的数字是准确的。 如果您将数字2/3创建为0.6666666666666667,则所有操作都将其视为完全相同。 最低有效数字中的该错误可能最终在以后的计算中传播到更大的错误,但这是优秀代码应该处理的事情,使用尽可能最小化这些问题的算法。

然而,正如我所说,计算机会做他们被告知要做的事情。 因此,编写的包使用所谓的区间运算。 然后可以将数字描述为区间,因此我们可以创建2/3作为区间[0.6666666666666666,0.6666666666666667]。 我们可以按时间间隔,加法,减法,乘法等操作。这些操作通常会在我们操作它们时看到间隔宽度扩大。

但事实是,即使你使用区间算术工具,你必须在一开始就知道你的数字中的有效位数。 如果您创建一个2.2的数字,将其存储为double,那么计算机实际上会尝试将该数字存储为2.200000000000000,并假设所有数字都完全正确。 实际上,当然,因为采用了浮点运算,所以该数字实际上将作为二进制数存储在内部。 所以2.2可能会有效地存储为数字:

2.20000000000000017763568394002504646778106689453125

因为大多数小数部分数字不能完全以二进制形式表示。 同样,必须谨慎使用所有软件,但也必须始终由使用这些工具的人员了解他们的数字的真正含义。

最后一点很重要。 许多人将计算机产生的数字视为真理,就像计算机之神在石碑上传下来一样。 如果计算机打印出1.4523656535725,他们相信他们所看到的每一个数字。 实际上,必须在这里应用常识,要知道这个数字可能是由只有3位有效数字的数据生成的,因此您可以选择仅依赖该数字的前几位有效数字。 当然,这就是为什么你在学校里学习这个概念,知道应该信任什么,不信任什么。 但请记住 - 计算机通常会无限信任。 是您必须应用过滤器。

我使用格式化程序来做到这一点。 这是一个带有测量a和错误a_error的示例。

a = 0.0595269489794585
a_error = 0.00089489789798
sig_fig_pos = abs(int(f'{G_err:e}'.split('e')[-1]))
a = float(f'{a:.{sig_fig_pos }f}')
a_error = float(f'{a_error:.{sig_fig_pos }f}')
print(a, '±', a_error)

将调整 sig figs 的数量

0.0595 ± 0.0009

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM