Python中有没有办法计算double / float / etc中的重要数字?我没有看到一个简单的方法来做到这一点,但我希望它能在库中。
提前致谢。
答案 0 :(得分:4)
没有。重要的数字只是没什么大不了的,并且在计算机语言中得不到多少支持。进行实际计算的人需要误差棒,这些误差棒具有更高的精度 - 实际测量表明非常精确的事情,例如“这是0.11±0.03mm”而不是说不太精确的陈述“这是0.1毫米”或“这是0.11毫米” “即使你的不精确实际上并没有达到10的幂,你也会选择10的幂。
答案 1 :(得分:2)
您可能对任意精度浮点库感兴趣,例如:
答案 2 :(得分:1)
计算机根本不会以这种方式工作,至少,除非他们被编程这样做。假设你给他们的数字是准确的。如果您将数字2/3创建为0.6666666666666667,则所有操作都将其视为完全相同。最低有效数字中的错误可能最终会在以后的计算中传播到更大的错误,但这是优秀代码应该处理的事情,使用尽可能最小化这些问题的算法。
正如我所说的那样,计算机按照他们的要求去做。因此,编写的包使用所谓的区间运算。然后可以将数字描述为区间,因此我们可以创建2/3作为区间[0.6666666666666666,0.6666666666666667]。我们可以按时间间隔,加法,减法,乘法等进行操作。这些操作通常会在我们使用它们时看到间隔宽度扩大。
然而,事实是,即使你使用区间算术工具,你必须在一开始就知道你的数字中的有效位数。如果您创建一个2.2的数字,将其存储为double,那么计算机实际上会尝试将该数字存储为2.200000000000000,并假设所有数字都完全正确。实际上,当然,因为采用了浮点运算,所以该数字实际上将作为二进制数存储在内部。所以2.2可能会被有效地存储为数字:
2.20000000000000017763568394002504646778106689453125
因为大多数小数部分数字不能完全以二进制形式表示。同样,必须小心谨慎地使用所有软件,但也应始终由使用这些工具的人来理解他们的数字真正含义。
最后一点很重要。许多人将计算机产生的数字视为真理,就像计算机之神在石碑上传下来一样。如果计算机打印出1.4523656535725,他们相信他们所看到的每一个数字。实际上,必须在这里应用常识,要知道这个数字可能是由只有3位有效数字的数据生成的,因此您可以选择仅依赖该数字的前几位有效数字。当然,这就是为什么你在学校里学习这个概念,知道应该信任什么,不信任什么。但请记住 - 计算机通常会无限信任。您必须应用过滤器。
答案 3 :(得分:1)
我在另一个问题中找到了这篇文章的解决方案:
Python counting significant digits
这里的想法是你将float作为String传递给方法,然后该方法使用正则表达式通过分割"e"
所在的字符串来计算有效数字的数量(对于科学格式的浮点字符串) )和点的位置(对于普通的浮点字符串)。
它似乎可以很好地工作到8位有效数字,但在第9次之后不能保证这种行为。
不过,我相信这比
更好"重要数字不是那么重要而且收效甚微 支持计算机语言"
响应。这可能并不容易,但你绝对可以做到,即使不是很完美。
答案 4 :(得分:0)
内置的 Decimal library 可以很好地解决这个问题,因为它解决了使用基于硬件的浮点数的问题。它有一个内部表示,只包含有效数字和指数。所以你可以用它来计算这样的有效数字:
from decimal import Decimal
def count_sigfigs(numstr):
return len(Decimal(numstr).normalize().as_tuple().digits)
这对于很多示例都非常有效,例如这些示例(来自 this related question)。请注意,您必须将数字作为字符串输入才能正常工作。使用浮点数会因为它们的硬件表示而搞砸。
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 个 sigfig 的数字不太适用。这只是给 1。所以它需要改进以涵盖所有情况。它也为“0”给出 1,尽管通常应该给出 0。
如果去掉 normalize
,则它适用于 1.000
,但不适用于 3000(它表示 4 而不是 1)。