私は最近、Java の浮動小数点計算の問題を研究し、インターネットから関連情報を検索し、いくつかの整理とデバッグを経て、最終的にこの記事を完成させました。誰でもエラーや問題を指摘することができます。
Java では、float で宣言された変数は単精度浮動小数点数であり、double で宣言された変数は倍精度浮動小数点数です。その名前が示すように、double 型エンティティは float の 2 倍のメモリ領域を占有します。 float は 4 バイト、double は 8 バイトです。 float 型や double 型のデータは計算結果を正確に表現できません。これは、float 型や double 型は不正確な計算であるためです。これは次のコードで確認できます。
次のようにコードをコピーします。
パブリッククラステスト
{
public static void main(String[] args)
{
System.out.println(0.05 + 0.01);
System.out.println(1.0 - 0.42);
System.out.println(4.015 * 100);
System.out.println(123.3 / 100);
}
}
実行した結果は次のとおりです。
0.060000000000000005
0.5800000000000001
401.49999999999994
1.23299999999999999
望ましい効果を得るには、java.text.DecimalFormat を使用して浮動小数点数をフォーマットしてみることができます。
DecimalFormat は、特定の形式に従って数値を書式設定できます。一般的に使用される書式設定文字は #、0 などです。例:
次のようにコードをコピーします。
System.out.println(new java.text.DecimalFormat("0.00").format(3.125));
System.out.println(new java.text.DecimalFormat("0.00").format(3.135));
しかし、結果は次のようになります。
3.12
3.14
これは、DecimalFormat が半偶数丸め (ROUND_HALF_EVEN) を使用するためです。簡単に言うと、5 に丸めるときに最も近い偶数に依存します。したがって、DecimalForamt を使用して信頼できる浮動小数点数を取得することはできません。最後に、より正確な計算のために BigDecimal の使用を検討できます。
BigDecimal は、浮動小数点数に関連する複数のコンストラクターを提供します。
次のようにコードをコピーします。
BigDecimal(double val) double を BigDecimal に変換します。
BigDecimal(String val) BigDecimal の String 表現を BigDecimal に変換します。
ただし、二重パラメータを使用してオブジェクトを作成すると、値が不正確になります。String を使用してオブジェクトを作成するのが最も正確です。
例えば:
次のようにコードをコピーします。
BigDecimal bd1=新しい BigDecimal(0.05);
System.out.println(bd1.toString());
BigDecimal bd2=new BigDecimal("0.05");
System.out.println(bd2.toString());
結果を取得します。
0.05000000000000000277555756156289135105907917022705078125
0.05
したがって、得られる結果が最も正確になるように、最終的には String を使用してオブジェクトを作成する必要があります。さらに、double の数値の場合は、BigDecimal.valueOf(double val) を使用することもできます。その理由は非常に簡単です。
次のようにコードをコピーします。
public static BigDecimal valueOf(double val)
{
新しい BigDecimal(Double.toString(val)) を返します。
}
最後に注意すべき点は、BigDecimal の加算、減算、乗算、除算は実際には最終的に新しい BigDecimal オブジェクトを返すということです。BigDecimal は不変であるため、各演算中に新しいオブジェクトが生成されます。が実行された場合、a は加算操作後の値を保存しません。正しい使用法は a=a.add(b) です。