3

我正在处理R非常小的数字,这些数字反映了最大似然估计算法中的概率。其中一些数字小到 1e-155(或更小)。然而,当发生像求和这样简单的事情时,精度水平会被截断为最不精确的水平,从而破坏我的计算精度并产生毫无意义的结果。

例子:

    > sum(c(7.831908e-70,6.002923e-26,6.372573e-36,5.025015e-38,5.603268e-38,1.118121e-14,  4.512098e-07,4.400717e-05,2.300423e-26,1.317602e-58))
    [1] 4.445838e-05

从示例中可以看出,此计算的基数是 1e-5 ,它以非常粗鲁的方式将敏感计算四舍五入。

有没有解决的办法?为什么会R选择这种奇怪的自动行为?也许它不是真的这样做,我只是看到截断形式的结果?在这种情况下,具有正确精度的实际数字是否存储在变量中?

4

3 回答 3

7

您的总和没有精度损失。但如果你担心它,你应该使用多精度库:

library("Rmpfr")

x <- c(7.831908e-70,6.002923e-26,6.372573e-36,5.025015e-38,5.603268e-38,1.118121e-14,  4.512098e-07,4.400717e-05,2.300423e-26,1.317602e-58)

sum(mpfr(x, 1024))

# 1 'mpfr' number of precision  1024   bits 
# [1] 4.445837981118120898327314579322617633703674840117902103769961398533293289165193843930280422747754618577451267010103975610356319174778512980120125435961577770470993217990999166176083700886405875414277348471907198346293122011042229843450802884152750493740313686430454254150390625000000000000000000000000000000000e-5
于 2013-09-11T13:56:56.150 回答
6

您的结果仅在显示中被截断。

尝试:

x <- sum(c(7.831908e-70,6.002923e-26,6.372573e-36,5.025015e-38,5.603268e-38,1.118121e-14,  4.512098e-07,4.400717e-05,2.300423e-26,1.317602e-58))

print(x, digits=22)
[1] 4.445837981118121081878e-05

您可以在以下位置阅读有关打印行为的更多信息?print.default


您还可以设置一个选项 - 这会将所有呼叫附加到print

options(digits=22)
于 2013-09-11T13:54:29.173 回答
1

你听说过浮点数吗?只要结果保持在之间,乘法或除法的精度(重要数字)不会损失 1.7976931348623157·10^308 to 4.9·10^−324 (详见链接)

所以如果你这样做1.0e-30 * 1.0e-10结果将是1.0e-40

但如果你这样做1.0e-30 + 1.0e-10结果将是1.0e-10

为什么?

-> 可通过计算机工作的有限数集。(64 位最大 2^64 64 位数字的不同表示)

而不是像整数那样使用直接转换(它们代表from ~ -2^62 to +2^62每个整数 -> about from -10^16 to +10*16)还是存在像浮点这样的聪明方法?从1.7976931348623157·10^308 to - 4.9·10^−324它可以代表/近似有理数?

因此,在浮点中,为了实现更广泛的范围,求和的精度被牺牲了,在求和或减法过程中会损失精度,因为有效数字可以由(浮点数的小数部分的 52 位)表示64 位)小于log10(2^52) ~ 16. 如果您寻找一个基本的日常示例,summary(lm),当参数的 p 值接近零时,summary() 输出 <2.2e-16(多么巧合)。

为什么限制为 64 位?CPU 有专门针对 64 位浮点运算(64 位 IEEE 754 标准)的执行单元,如果使用 128 位浮点等更高的精度,性能会降低 10 倍或更多,因为 CPU 需要拆分数据和运算在多个 64 位数据和操作中。

https://en.wikipedia.org/wiki/Double-precision_floating-point_format

于 2018-06-28T11:08:20.847 回答