为什么这两个 sum 命令之间存在差异?

为什么这两个 sum 命令之间存在差异?

我有一个场景

我使用以下两个命令计算特定列的总和

谁能详细解释一下该命令实际上正在执行什么

第一个命令[当用于计算特定列的总和时]

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

第二个命令[当用于计算特定列的总和时]

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

当使用两个命令计算的总和不同时。为什么会这样呢?

这是输出: 在此输入图像描述 这是用于计算的文件[请下载并测试](链接已被版主删除,可能存在安全问题)

答案1

差异在于gawk手动的状态:

二进制浮点表示和算术是不精确的。像这样的简单值0.1无法使用二进制浮点数精确表示,并且浮点数的精度有限意味着运算顺序或中间存储精度的轻微变化都可能改变结果。更糟糕的是,对于任意精度浮点运算,您可以在开始计算之前设置精度,但您无法确定最终结果中有效小数位数。

gawk是 GNU awk。它支持-M

-M
--bignum

选择数字的任意精度算术。如果gawk未编译为使用 GNU MPFR 和 MP 库,则此选项无效。

awk可能相当于也可能不相当于gawk.在我的 Debian 9 中,以下两个命令都会产生25396577843.76

LC_NUMERIC=C gawk -M -v PREC=60 -F '"?\\|"?' '{T+=$(2)*1000} END {printf "%.2f\n",T/1000}' demofile.txt
LC_NUMERIC=C gawk -M -v PREC=60 -F '"?\\|"?' '{T+=$(2)} END {printf "%.2f\n",T}' demofile.txt

虽然printf "%.4f\n",T我还是能看出区别。增加PREC以获得更好的结果。

该网站解释了根本问题:
每个程序员都应该了解的浮点运算知识

相关内容