什麼是對浮點值求和的更好方法 - 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

相關內容