什么是对浮点值求和的更好方法 - unix 将 8 到 9 范围内的值求和给出了不正确的总和

什么是对浮点值求和的更好方法 - unix 将 8 到 9 范围内的值求和给出了不正确的总和

我有一个场景

我遇到问题,因为 UNIX 总和高达 8 到 9 的比例给了我不正确的总和,如何修复它?

我使用的命令

awk -F '"?\\|"?' '{T+=$(2)} END {printf "%.2f\n",T}' demofile.txt

这是上一个问题的链接 为什么这两个 sum 命令之间存在差异?

有什么更好的方法来处理它,以便我可以获得准确的总和

使用 awk 或 bc 或 dc

演示数据

1|"12.8"|demo1
2|"13.5678341234567"|demo1
3|"14.578"|demo1
4|"15.58"|demo1
5|"16.56784"|demo1
6|"17.578"|demo1
7|"18.678"|demo1
8|"19.568890123"|demo1
9|"20.588792"|demo1

答案1

您没有说出文件大小(即您要添加的行数)。在网站显示为“危险”和“欺诈警报”之前,下载量为 18.3MB。如果平均行长度为 18,则添加了一百万个浮点,并且我们不知道值的跨度。您在问题中显示的总数为 13.2 位,因此每行的平均值约为 7 位,可变性未知。

如果您继续将 27.865326635297 这样的值添加到接近 13 个整数位的运行总计中,则只有 27.87(四舍五入)部分才能进入总计,因为 .00532... 超出了 15 或16 位结果范围。有时这些错误会相互抵消,有时则不会:蒙特卡罗算术。

检查 awk --version 的输出。如果它提到 MPFR 和 MP,则您的 awk 是使用扩展精度数学编译的。您只需将 -M 113 添加到 awk 命令中即可。这就是让您进行四倍精度实数算术的尾数长度——33 位精度。

www.gnu.org/software/gawk/manual/gawk.html#Arbitrary-Precision-Arithmetic

答案2

这是一种基于直流电命令(假设编译的精度足够)。它用 dc 命令修饰第二列,并以 60 位(200 位)精度工作。

它在之前提供的 10 条数据线上运行,加上几个极值。它显示中间总和:要删除这些,请删除 awk 发出 $2 的 \n 之前的 'p'。

Paul--) cat awkToDc
#! /bin/bash

function Data { cat <<'EOF'
1|"12.8"|demo1
2|"13.5678341234567"|demo1
3|"14.578"|demo1
4|"15.58"|demo1
5|"16.56784"|demo1
6|"17.578"|demo1
7|"18.678"|demo1
8|"19.568890123"|demo1
9|"20.588792"|demo1
10|"55555555555555555555000000000000"|demo1
11|"20.588792"|demo1
12|"0.000000000000000000077777777777"|demo1
EOF
}

function dataDC {

    AWK='
BEGIN { FS = "\042"; printf ("60 k 0\n"); }
{ printf ("%s + p\n", $2); }
END { printf ("p q\n"); }
'
    awk "${AWK}"
}

对发出的 dc 命令的澄清(采用逆波兰表示法):

“60 k”设置算术精度,“0”初始化总数。
'+' 将 $2 中的值添加到总计中。 'p' 打印运行总计以供说明。
'p q' 打印最终总数,然后退出。

    Data | dataDC | dc

Paul--) ./awkToDc
12.8
26.3678341234567
40.9458341234567
56.5258341234567
73.0936741234567
90.6716741234567
109.3496741234567
128.9185642464567
149.5073562464567
55555555555555555555000000000149.5073562464567
55555555555555555555000000000170.0961482464567
55555555555555555555000000000170.096148246456700000077777777777
55555555555555555555000000000170.096148246456700000077777777777
Paul--) 

现在有四种经过测试的技术(针对 722277 行的测试文件),并具有准确度评级。

使用精度为 200 位的 gawk 和精度为 60 位的 dc,两者都同意相同的 33 位总数,我怀疑这是准确的。

25396577843.7560139069641121618832

在标准 IEEE 精度(应为 15 或 16 位)中使用 gawk 仅与这些数字中的前 12 位一致。我假设一百万次加法会削弱准确性,因为指数变得更加不相交。

25396577843.7769622802734375

我也在标准 awk 中找到了递归加法算法。这首先根据 NR 的最后 5 位数字添加值,以形成 100,000 个小计。然后将这些数字相加,将位数减少到 4、3、2、1,最后得出一个总和。因此每个数字只能进行 60 次加法。该结果与高精度结果的前16位一致,符合预期。

25396577843.756011962890625

答案3

查看卡汉求和,它尝试跟踪舍入误差并进行补偿。对于如此巨额的资金来说是必须的。

答案4

cvstoolbc

$ csvtool -t '|' col 2 A | paste -sd + - | bc
149.5073562464567

相关内容