【问题标题】:Counting significant figures in Python?在 Python 中计算有效数字?
【发布时间】:2011-12-27 10:21:48
【问题描述】:

在 Python 中有没有办法计算 double/float/etc 中的有效数字?我没有看到一种简单的方法来做到这一点,但我希望它会出现在库中。

提前致谢。

【问题讨论】:

  • 一个数字本身并没有个有效数字,您可以指定一个数字显示多少个有效数字。这是你要求做的吗?
  • 您如何定义“重要数字”?
  • @tjm 一个数字本质上确实有有效数字。有效数字的数量传达了测量的准确性。见en.wikipedia.org/wiki/…
  • @Will,我不同意。例如,链接中的第三点指出:“包含小数点的数字中的尾随零很重要。”好吧,有了它,就拿 2.25、2.250 和 2.2500000 表示。每种情况下的数字都是 2 和四分之一,但它们分别有 3、4 和 8 位有效数字。那么,数字 2 和四分之一的有效数字的固有位数是多少?
  • @tjm 啊,我明白你的意思了。我误解了你的说法。任何 sig fig 查找函数都必须将数字的字符串表示形式作为输入。

标签: python math chemistry significant-digits


【解决方案1】:

没有。有效数字只是没什么大不了的,并且在计算机语言中几乎没有得到支持。进行实际计算的人需要误差线,它具有更高的精度——实际测量会说非常精确的东西,比如“这是 0.11 ± 0.03 毫米”,而不是说“这是 0.1 毫米”或“这是 0.11 毫米”这样不太精确的陈述” 这使您选择了 10 的幂,即使您的不精确性实际上并未落在 10 的幂。

【讨论】:

  • 重要数字非常重要,并且对于跟踪测量的准确性是必要的,即使有误差线也是如此。有几个著名的例子,忽略有效数字会导致错误的结果。
  • 有效数字对学童来说非常重要,因为它们易于使用——但在“有效数字说话”中,度量 0.10 表示“0.10 ± 0.01”,0.100 表示“0.100 ± 0.001”。 ”我的观点是,有效数字是对更一般的测量误差概念的简化,因此科学数学库将支持误差,而不是有效数字。因为,正如我在回答中所暗示的那样,错误往往具有各种价值,而且很少会恰好落在 10 的幂上。 :)
  • 不要对无花果那么失望,除了学童之外,它们对其他人都很重要。例如,当测量误差的准确性不那么重要时,物理学家就会一直使用它们。
  • 你是对的——我应该说“在手工工作时很重要,或者在为实际出版做准备之前非正式地”——我会回去调整我的“学童”措辞,如果不是因为 31 分钟过去了,而且推荐是不可编辑的。 叹息
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    Python counting significant digits

    这里的想法是您将浮点数作为字符串传递给方法,然后该方法使用正则表达式来计算有效数字的数量,方法是拆分 "e" 所在的字符串(对于科学格式的浮点字符串)和点在哪里(对于普通的浮点字符串)。

    它似乎在 8 位有效数字内运行良好,但不能保证 9 位之后的行为。

    不过,我相信这比

    “有效数字没什么大不了的 支持计算机语言”

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

    【讨论】:

      【解决方案4】:

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

      不过,正如我所说,计算机会按照指示执行操作。所以有一些包使用所谓的区间算术。然后可以将一个数字描述为一个区间,因此我们可以创建 2/3 作为区间 [0.6666666666666666,0.6666666666666667]。我们可以对区间进行操作,如加法、减法、乘法等。这些操作通常会在我们操作时看到区间宽度扩大。

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

      2.20000000000000017763568394002504646778106689453125

      因为大多数十进制小数不能以二进制形式精确表示。同样,所有软件都必须小心,但使用这些工具的人也必须始终了解他们的数字的真正含义。

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

      【讨论】:

        【解决方案5】:

        内置的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 个 sigfigs 的数字。这只是给出 1。所以它需要改进以涵盖所有情况。它也为“0”给出 1,尽管通常应该给出 0。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-06
          • 1970-01-01
          • 2016-06-21
          • 2016-01-16
          • 2019-03-04
          • 1970-01-01
          相关资源
          最近更新 更多