為什麼這兩個 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以獲得更好的結果。

該網站解釋了根本問題:
每個程式設計師都應該了解的浮點運算知識

相關內容