【问题标题】:Summation of large numbers in python yields the maximal parameterpython中大量数字的总和产生最大参数
【发布时间】:2017-07-24 10:36:03
【问题描述】:

在我的程序中,我使用 numpy 来获取数字的指数,然后我使用 sum 函数来总结它们。 我注意到总结这些大数字,无论有没有 numpy,都会导致返回的最大参数保持不变。

exp_joint_probabilities=[  1.57171938e+81,   1.60451506e+56,   1.00000000e+00]
exp_joint_probabilities.sum()
=> 1.571719381352921e+81

python 也一样:

(1.57171938e+81+1.60451506e+56+1.00000000e+00)==1.57171938e+81
=>True

这是近似的问题吗?我应该使用更大的数据类型来表示数字吗? 对于此类计算,我怎样才能获得更准确的结果?

【问题讨论】:

    标签: python numpy math exponent


    【解决方案1】:

    你可以使用the decimal standard library:

    from decimal import Decimal
    
    a = Decimal(1.57171938e+81)
    b = Decimal(1.60451506e+56)
    d = a + b
    print(d)
    print(d > a and d > b)
    

    输出:

    1.571719379999999945626903708E+81
    True
    

    您可以在之后将其转换回浮点数,但这会导致与之前相同的问题。

    f = float(d)
    print(f)
    print(f > a and f > b)
    

    输出:

    1.57171938e+81
    False
    

    请注意,如果您将Decimals 存储在您的numpy 数组中,您将失去快速矢量化操作,如numpy does not recognize Decimal objects。虽然它确实有效:

    import numpy as np
    
    a = np.array([1.57171938e+81, 1.60451506e+56, 1.00000000e+00])
    d = np.vectorize(Decimal)(a)  # convert values to Decimal
    print(d.sum())
    print(d.sum() > d[0]
    

    输出:

    1.571719379999999945626903708E+81
    True
    

    【讨论】:

    • 您仍然首先将数字转换为 64 位浮点近似值,然后将这些近似值转换为十进制。要将输入直接转换为十进制,请将它们作为字符串,a = Decimal("1.57171938e+81") 和b = Decimal("1.60451506e+56") 然后a+b 给出更正确的结果Decimal('1.571719380000000000000000160E+81')
    【解决方案2】:

    1.57171938e+81 是一个 81 位数字,您只需输入前 9 个数字。1.60451506e+56 是一个小得多的数字,只有 56 位数字。

    你期待什么样的答案?第一个完全使第二个相形见绌。如果您想要与原始数字具有相似精度的东西(这就是您使用浮点数得到的),那么答案就是正确的。

    你可以使用整数:

    >>> a = int(1.57171938e+81)
    >>> b = int(1.60451506e+56)
    >>> a
    571719379999999945626903548020224083024251666384876684446269499489505292916359168L
    >>> b
    160451506000000001855754747064077065047170486040598151168L
    >>> a+b
    1571719379999999945626903708471730083024253522139623748523334546659991333514510336L
    

    但这有多大用处取决于你。

    【讨论】:

      【解决方案3】:

      这似乎是近似的问题:

      >>> 1.57171938e+81 + 1.60451506e+65 > 1.57171938e+81
      <<< True
      
      >>> 1.57171938e+81 + 1.60451506e+64 > 1.57171938e+81
      <<< False
      

      你可以通过转换为 int 来解决这个问题:

      >>> int(1.57171938e+81) + int(1.60451506e+64) > int(1.57171938e+81)
      <<< True
      

      【讨论】:

      • long 演员表在 Python 3.x 中不起作用。转换为 int 确实可以在那里工作,我相信这也适用于 Python 2.x。
      • int 确认在 Python 2.7 中为此目的工作
      • 哦,我不知道int 在这种情况下有效,我会编辑我的答案,谢谢。
      猜你喜欢
      • 2016-09-03
      • 2020-02-04
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多