これら2つのsumコマンドの間に違いがあるのはなぜですか?

これら2つのsumコマンドの間に違いがあるのはなぜですか?

シーンがあります。

次の2つのコマンドを使用して、特定の列の合計を計算します。

このコマンドが実際に行うことを詳しく説明できる人はいますか?

最初の命令[特定の列の合計を計算するときに使用する場合]

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

2番目の命令[特定の列の合計を計算するときに使用する場合]

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

2つのコマンドを使用して計算した合計が異なる場合。なぜですか?

出力は次のとおりです。 ここに画像の説明を入力してください。 計算に使用されるファイルです。 [ダウンロードしてテストしてください](オペレータがリンクを削除しました。セキュリティ上の問題がある可能性があります。)

答え1

違いは次のとおりです。gawk手動状態:

バイナリ浮動小数点表現と算術が正確ではありません。このような単純な値は、0.1バイナリ浮動小数点数を使用して正確に表現することはできず、浮動小数点数の制限された精度は、演算順序または中間記憶装置の精度がわずかに変更されると結果が変わることがあることを意味します。さらに、任意精度浮動小数点演算を使用すると、計算を開始する前に精度を設定できますが、最終結果で有効小数点数を決定することはできません。

gawkそれはGNUですawk。それは支える-M:

-M
--bignum

選択した数値の任意精度算術。gawkGNU 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

このウェブサイトは根本的な問題を説明します。
すべてのプログラマが浮動小数点演算について知っておくべきこと

関連情報