printfの奇妙な浮動小数点丸め動作

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

私はこれがおそらく微妙な浮動小数点エラーであることを知っています(しかしそれは大きな数字ではありません、そうですか?)。だから誰でもこれについて言うことができますか?

これに対する回避策も非常に歓迎されています(今はそれを実行に移そうとしています)。

ベストアンサー1

予想通り、「丸め」または「銀行員の丸め」です。

関連ウェブサイトの回答説明する。

この規則が解決しようとする問題は(小数点の最初の桁までの数字について)、

  • x.1からx.4に降ります。
  • x.6からx.9に丸めます。

下に4つ、上に4つ。
四捨五入のバランスを維持するには、x.5を四捨五入する必要があります。

  • 戻る一度下に次へ。

これは、「最も近い「偶数」に丸める」という規則に従って行われます。

コードから:

LC_NUMERIC=C printf '%.0f ' "$value"
echo "$value" | awk 'printf( "%s", $1)'


オプション:

数値を四捨五入する方法には合計4つの方法があります。

  1. 銀行員の法則を説明しました。
  2. +無限大方向に丸めます。丸め(正の場合)
  3. -無限大方向に丸めます。降り(羊水の場合)
  4. 0に向かって丸めます。素数(正または負)を削除します。

戻る

本当に「丸め+infinite」が必要な場合は、awkを使用できます。

value=195.5

echo "$value" | awk '{ printf("%d", $1 + 0.5) }'
echo "scale=0; ($value+0.5)/1" | bc

下に

本当に「下り(方向-infinite)」が必要な場合は、次のものを使用できます。

value=195.5

echo "$value" | awk '{ printf("%d", $1 - 0.5) }'
echo "scale=0; ($value-0.5)/1" | bc

小数点以下の桁数を切り捨てます。

小数点(点の後のすべて)を削除します。
シェルを直接使用することもできます(ほとんどのシェルで動作 - POSIX)。

value="127.54"    ### Works also for negative numbers.

echo "${value%%.*}"
echo "$value"| awk '{printf ("%d",$0)}'
echo "scale=0; ($value)/1" | bc

おすすめ記事