【问题标题】:computing -log10 of very small values计算非常小的值的 -log10
【发布时间】:2013-02-07 21:56:15
【问题描述】:

有没有办法计算 -log10 值。

值非常小,即 3*e-178 或 e-320。

我已经尝试使用公式 log((1/value),10) 打开办公室,它工作正常,但是当它遇到极小的值时,它会给出错误,比如不可能除以零。

我想当我使用 perl、python 或 R 时也会发生同样的情况。

请帮助将这些值转换为 -log10value

谢谢

注意:我想计算以 10 为底的负对数

【问题讨论】:

  • 你从哪里得到你的数字,它们代表什么?
  • 我认为任何零假设在这些值上都可能是错误的。

标签: python perl r openoffice.org


【解决方案1】:

在 R 中:

x <- 3e-320
log10(x)
#-319.5229

y <- 3*exp(-320)
log10(y)
#-138.4971

对于大指数:

library(Brobdingnag)
x <- 3*as.brob(10)^(-1000)
log10(x)
#-999.5229

y <- 3*as.brob(exp(1))^(-1000)
log10(y)
#-433.8174

或者:

log10(3)-1000
#-999.5229

【讨论】:

    【解决方案2】:

    perl one 班轮:

    perl -e 'print log($ARGV[0])/log(10),"\n"' 3e-320
    

    输出:

    -319.522883580228
    

    【讨论】:

    • 它在 Ubuntu box (perl v5.14.2) 上产生Can't take log of 0 at -e line 1.,即3e-320 太小了。虽然it works on ideone.
    • @J.F.Sebastian:它适用于 Debian 2.6.32 / perl 5.10 和 windows / perl 5.14 直到 3e-324,但在 3e-325 失败
    【解决方案3】:

    在 Python 中:

    import math
    math.log10(3e-320)
    

    返回

    -319.5228835802284
    

    要以非常小的值获取有关 Python 功能的更多信息:

    import sys
    sys.float_info
    

    返回(取决于您的系统):

    sys.float_info(max=1.7976931348623157e+308,
                   max_exp=1024,
                   max_10_exp=308,
                   min=2.2250738585072014e-308,
                   min_exp=-1021,
                   min_10_exp=-307,
                   dig=15,
                   mant_dig=53,
                   epsilon=2.220446049250313e-16,
                   radix=2,
                   rounds=1)
    

    虽然math.log10(3e-320) 返回正确的值,但math.log10(3e-325) 引发ValueError: math domain error

    【讨论】:

      【解决方案4】:

      您应该能够从其他答案中看出,更好的公式是 -log10(value),或者在 OpenOffice Calc 电子表格中,=-LOG(value,10)。

      但是,您需要确保输入的值不会下溢为 0。 -LOG(3E-178,10) 有效 (177.522879),但 -LOG(1E-320,10) 失败,因为 1E-320 下溢为 0 并出现 Err.502。 (这可能就是你使用 1/value 的原因。)

      【讨论】:

        【解决方案5】:

        您可以使用decimal module in Python 以任意精度计算 log10,例如,使用默认精度:

        from decimal import Decimal as D
        
        for f in [3e-178, 1e-320, 3e-320, "1e-325", "3e-325"]:
             print("%s\t%s" % (f, D(f).log10()))
        

        Output

        3e-178  -177.5228787452803375835172220
        1e-320  -320.0000048349480421542963792
        3e-320  -319.5228835802283797170013513
        1e-325  -325
        3e-325  -324.5228787452803375627049721
        

        或者:

        import decimal
        
        decimal.getcontext().prec = 70
        for f in [3e-178, 1e-320, 3e-320, "1e-325", "3e-325"]:
             print("%s\t%s" % (f, decimal.Decimal(f).log10()))
        

        Output

        3e-178  -177.5228787452803375835172220093158130425818111446701314507791687173572
        1e-320  -320.0000048349480421542963791664378178773271498211156984605956663618384
        3e-320  -319.5228835802283797170013512631827025681270209569250025957658007215332
        1e-325  -325
        3e-325  -324.5228787452803375627049720967448846907998711358093041351701343596948
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-10-14
          • 2021-03-24
          • 1970-01-01
          相关资源
          最近更新 更多