丸い浮動小数点数

丸い浮動小数点数

コマンドラインでIEEE 754浮動小数点数を正しく丸める方法は?

出力数字の精度(小数点以下の桁数)を指定したいと思います。

たとえば、6.66精度に合わせて丸める1必要があります。6.7詳細については、下の表を参照してください。

Value   Precision  Rounded
6.66    0          7
6.66    1          6.7
6.66    2          6.66
6.66    3          6.660
6.666   3          6.666
6.6666  3          6.667

これは対話型シェルで機能する必要がありますが、理想的には本番シェルスクリプトで使用できるほど強力です。

ベストアンサー1

丸い浮動小数点数

「浮動小数点数の丸め」とはどういう意味ですか?
簡単なようです…私たちの学校の数学の本はどこにありますか…

いいえ、我々は浮動小数点数に関連することは容易ではないことをすでに知っています。

まず、さまざまな丸めモードがあります。

集める?
四捨五入しますか?
ゼロに丸めますか?
最も近い値に丸め - 偶数ですか?
最も近い値に丸め - 0から離れていますか?

極端な状況に対処する方法は?どのようなケースが極端な場合であるかをどうやって知ることができますか?

いいですね。 IEEE 754標準実装を使用し、システムにそれを処理させる方が良いと思います。

標準浮動小数点算術に基づいてシェル内の浮動小数点数を四捨五入するには、次の 3 つのステップが必要です。

  • コマンドライン引数の入力テキストを標準浮動小数点数に変換します。
  • 浮動小数点数は、一般的なIEEE 754実装を使用して丸められます。
  • 出力のために数値を文字列にフォーマットします。

シェルコマンドで判明しましたprintfすべてを行うことができます。で説明されているように、フォーマットの仕様に従って数値を印刷するために使用できます。man 3 printf。出力形式で必要な場合、数値は標準的な方法で暗黙的に丸められます。

注文する

入力をコマンドライン引数として使用してx数値精度に丸めます。p

printf "%.*f\n" "$p" "$x"

または、シェルパイプラインでx標準入力を入力とp引数として使用します。

echo "$x" | xargs printf "%.*f\n" "$p"

例:

$ printf '%.*f\n' 0 6.66
7
$ printf '%.*f\n' 1 6.66
6.7
$ printf '%.*f\n' 2 6.66
6.66
$ printf '%.*f\n' 3 6.66
6.660
$ printf '%.*f\n' 3 6.666
6.666
$ printf '%.*f\n' 3 6.6666
6.667

悪い罠

領土に注意してください!.予想どおり、整数部分と小数部分の間の区切り記号を指定します。
しかし、ドイツ語のロケールでは何が起こるのかを確認してください。たとえば、次のようになります。

$ LC_ALL=de_DE.UTF-8 printf '%.*f\n' 3 6.6666
6,667

はい、そうです。6,667カンマ6 6 6 7。これは間違いなくスクリプトを台無しにします。
(しかし、ドイツの2人の顧客にのみ適用されます。現在、その顧客のためにデバッグしている開発者コンピュータは例外です。)

より強く

より強力にするには、以下を使用してください。

LC_ALL=C /usr/bin/printf "%.*f\n" "$p" "$x"

または

echo "$x" | LC_ALL=C xargs /usr/bin/printf "%.*f\n" "$p"

また、バリアント実装のマイナーな不一致を解決し、ドイツ語のロケールに設定してもエクスポートできない場合は、非常に汚れた効果を防ぐために組み込み/usr/bin/printfシェルの代わりにbashORを使用します。その後、組み込みを使用して...zshprintfLC_ALL,/usr/bin/printf.


%g指定された有効数字に丸めを参照してください。

おすすめ記事