浮動小数点数を機械の浮動小数点数 ( doubleなど) に丸める方法を知りたいです。数値 "0.01111116" は、機械の浮動小数点で表すことができません。一部の丸めモードでは、この数値は "0.011111159999999995" として表す必要がありますが、精度がいくらか失われます。しかし、Java でこれを完了する方法がわかりません。したがって、丸めモードを設定して、Java でマシンの浮動小数点数の正確な表現を取得する API を知りたいです。ありがとう!
3 に答える
プログラムのソース コードでリテラルについて話している場合0.01111116
、Java コンパイラはコンパイル時にそれを 2 進浮動小数点表現に変換します。
文字「0.01111116」を含む文字列について話している場合、(たとえば)を呼び出すと、バイナリ浮動小数点表現に変換されますDouble.parseDouble(...)
。
いずれにせよ、変換は舞台裏で行われ、実際の丸めを制御することはできません。しかし、ある意味でそれはばかげています。いくつかの丸めが発生するのは表現の性質に固有のものであり、結果は一般に、数学的な観点から得られる「最も正確な」と言われています...選択した浮動小数点型が与えられます。
変換で異なる丸め/切り捨てルールを使用することが本当に必要な場合は、事後にこれを行う (たとえば、変換された値を丸めるまたは切り捨てる) か、独自の String から浮動小数点への変換メソッドを実装することができます。
Java コンパイラがリテラルを変換する方法を変更することはできません。これは言語仕様の一部です。
したがって、丸めモードを設定して、Java でマシンの浮動小数点数の正確な表現を取得する API を知りたいです。
これについては別の考え方があります。
マシン浮動小数点数の正確な表現は、32 ビットまたは 64 ビットのバイナリ データです。a のビットをdouble
16 進数としてレンダリングするには、いくつかの方法があります。
Double::doubleToLongBits
またはDouble::doubleToRawLongBits
が続くとLong::toHexString
、正確ではあるが役に立たないレンダリングが得られる、またはDouble::toHexString
16 進浮動小数点表現を提供します。
これらのレンダリングはすべて の正確な (丸め誤差なし) 表現ですがdouble
、ほとんどの読者はそれらを理解できません。(「生の」バージョンは、バリアント NaN 値を含むエッジ ケースを最もよく処理します。)
には同等のメソッドがありますfloat
。
commons-math3 Precision を試すhttp://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html
double d = 0.1 + 0.2;
System.out.println(d);
d = Precision.round(d, 1); <-- 1 decimal place
System.out.println(d);
出力
0.30000000000000004
0.3