使用 printf 進行奇怪的浮點舍入行為
我在這個網站上閱讀了一些答案,發現
printf
四捨五入是可取的。然而,當我在實踐中使用它時,一個微妙的錯誤導致我出現以下行為:
$ echo 197.5 | xargs printf '%.0f' 198 $ echo 196.5 | xargs printf '%.0f' 196 $ echo 195.5 | xargs printf '%.0f' 196
請注意,舍入
196.5
變為196
。我知道這可能是一些微妙的浮點錯誤(但這不是一個很大的數字,嗯?),所以有人可以對此有所了解嗎?
對此的解決方法也非常受歡迎(因為我現在正在嘗試使用它)。
正如預期的那樣,它是“四捨五入”,或“銀行家四捨五入”。
一個相關的網站答案解釋它。
此類規則試圖解決的問題是(對於帶一位小數的數字),
- x.1 到 x.4 向下舍入。
- x.6 到 x.9 向上舍入。
那是4向下和4向上。
為了保持舍入平衡,我們需要捨入 x.5
- 上一次,下一次。
這是由規則完成的:«四捨五入到最接近的“偶數”»。
在程式碼中:
噓
LC_NUMERIC=C printf '%.0f ' "$value"
_
echo "$value" | awk 'printf( "%s", $1)'
選項:
總共有四種可能的方法來對數字進行四捨五入:
- 已經解釋過的銀行家規則。
- 向+無窮大方向舍入。向上取整(對於正數)
- 向 -infinite 舍入。向下舍入(對於正數)
- 向零舍入。刪除小數(正數或負數)。
向上
如果您確實需要“向上(朝
+infinite
)”,那麼您可以使用 awk:value=195.5
公元前
echo "$value" | awk '{ printf("%d", $1 + 0.5) }'
_
echo "scale=0; ($value+0.5)/1" | bc
向下
如果您確實需要“向下舍入(Toward
-infinite
)”,那麼您可以使用:value=195.5
公元前
echo "$value" | awk '{ printf("%d", $1 - 0.5) }'
_
echo "scale=0; ($value-0.5)/1" | bc
修剪小數。
刪除小數(點後的任何內容)。
我們也可以直接使用 shell(適用於大多數 shell - 是 POSIX):
value="127.54" ### Works also for negative numbers.
殼
echo "${value%%.*}"
awk
echo "$value"| awk '{printf ("%d",$0)}'
公元前
echo "scale=0; ($value)/1" | bc