シーンがあります。
次の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
選択した数値の任意精度算術。
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
。
このウェブサイトは根本的な問題を説明します。
すべてのプログラマが浮動小数点演算について知っておくべきこと