Java Language
BigDecimal
サーチ…
前書き
BigDecimalクラスは、算術演算(加算、減算、乗算、除算)、スケール操作、丸め、比較、ハッシュ、およびフォーマット変換のための演算を提供します。 BigDecimalは、不変の任意精度の符号付き10進数を表します。このクラスは、高精度計算を必要とする場合に使用するものとする。
BigDecimalオブジェクトは不変です
BigDecimalで計算したい場合、BigDecimalオブジェクトは不変であるため、返された値を使用する必要があります:
BigDecimal a = new BigDecimal("42.23");
BigDecimal b = new BigDecimal("10.001");
a.add(b); // a will still be 42.23
BigDecimal c = a.add(b); // c will be 52.231
BigDecimalsの比較
BigDecimals
を比較するには、 compareTo
メソッドを使用する必要があります。
BigDecimal a = new BigDecimal(5);
a.compareTo(new BigDecimal(0)); // a is greater, returns 1
a.compareTo(new BigDecimal(5)); // a is equal, returns 0
a.compareTo(new BigDecimal(10)); // a is less, returns -1
通常は、 equals
メソッドを使用しないでください。なぜなら、2つのBigDecimals
は、値が等しく、 位取りも等しい場合にのみ等しいとみなすからequals
。
BigDecimal a = new BigDecimal(5);
a.equals(new BigDecimal(5)); // value and scale are equal, returns true
a.equals(new BigDecimal(5.00)); // value is equal but scale is not, returns false
BigDecimalによる数学演算
この例では、BigDecimalsを使用して基本的な数学演算を実行する方法を示します。
1.追加
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a + b
BigDecimal result = a.add(b);
System.out.println(result);
結果:12
2.Subtraction
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a - b
BigDecimal result = a.subtract(b);
System.out.println(result);
結果:-2
3.多重化
2つのBigDecimal
掛け合わせると、結果はオペランドのスケールの合計と等しいスケールになります。
BigDecimal a = new BigDecimal("5.11");
BigDecimal b = new BigDecimal("7.221");
//Equivalent to result = a * b
BigDecimal result = a.multiply(b);
System.out.println(result);
結果:36.89931
結果のスケールが通過可能オーバーロード乗算方法使用変更しMathContext
結果のオペレータのためのルールを記述したオブジェクト、特定の精度と丸めモードを- 。使用可能な丸めモードの詳細については、Oracleのマニュアルを参照してください。
BigDecimal a = new BigDecimal("5.11");
BigDecimal b = new BigDecimal("7.221");
MathContext returnRules = new MathContext(4, RoundingMode.HALF_DOWN);
//Equivalent to result = a * b
BigDecimal result = a.multiply(b, returnRules);
System.out.println(result);
結果:36.90
4.区分
除算は、他の算術演算よりも少し複雑です。たとえば、以下の例を考えてみましょう。
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
BigDecimal result = a.divide(b);
System.out.println(result);
これで0.7142857142857143と似たものが得られると期待していますが、
結果: java.lang.ArithmeticException:終了しない小数点の展開。正確な表現可能な小数の結果はありません。
これは、5で2を除算したい場合、結果が終了小数点になると完全にうまく動作しますが、分割すると非終端の結果を返す数値に対してArithmeticException
ます。実世界のシナリオでは、分割中に発生する値を予測できないため、BigDecimal除算のスケールと丸めモードを指定する必要があります。縮尺と丸めモードの詳細については、 Oracleのマニュアルを参照してください。
たとえば、私はできる:
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a / b (Upto 10 Decimal places and Round HALF_UP)
BigDecimal result = a.divide(b,10,RoundingMode.HALF_UP);
System.out.println(result);
結果:0.7142857143
5.RemainderまたはModulus
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a % b
BigDecimal result = a.remainder(b);
System.out.println(result);
結果:5
6.Power
BigDecimal a = new BigDecimal("5");
//Equivalent to result = a^10
BigDecimal result = a.pow(10);
System.out.println(result);
結果:9765625
7.Max
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = MAX(a,b)
BigDecimal result = a.max(b);
System.out.println(result);
結果:7
8.Min
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = MIN(a,b)
BigDecimal result = a.min(b);
System.out.println(result);
結果:5
9.左に移動
BigDecimal a = new BigDecimal("5234.49843776");
//Moves the decimal point to 2 places left of current position
BigDecimal result = a.movePointLeft(2);
System.out.println(result);
結果:52.3449843776
10.右にポイントを移動する
BigDecimal a = new BigDecimal("5234.49843776");
//Moves the decimal point to 3 places right of current position
BigDecimal result = a.movePointRight(3);
System.out.println(result);
結果:5234498.43776
上記の例にはさらに多くのオプションとパラメータの組み合わせがあります(たとえば、分割メソッドの6つのバリエーションがあります)。このセットは非包括的なリストであり、いくつかの基本的な例が含まれています。
floatの代わりにBigDecimalを使う
浮動小数点型がコンピュータメモリ内で表される方法のため、この型を使用した演算結果は不正確になる可能性があります。一部の値は近似値として格納されます。これの良い例は金銭計算です。高精度が必要な場合は、他のタイプを使用する必要があります。 Java 7はBigDecimalを提供します。
import java.math.BigDecimal;
public class FloatTest {
public static void main(String[] args) {
float accountBalance = 10000.00f;
System.out.println("Operations using float:");
System.out.println("1000 operations for 1.99");
for(int i = 0; i<1000; i++){
accountBalance -= 1.99f;
}
System.out.println(String.format("Account balance after float operations: %f", accountBalance));
BigDecimal accountBalanceTwo = new BigDecimal("10000.00");
System.out.println("Operations using BigDecimal:");
System.out.println("1000 operations for 1.99");
BigDecimal operation = new BigDecimal("1.99");
for(int i = 0; i<1000; i++){
accountBalanceTwo = accountBalanceTwo.subtract(operation);
}
System.out.println(String.format("Account balance after BigDecimal operations: %f", accountBalanceTwo));
}
このプログラムの出力は次のとおりです。
Operations using float:
1000 operations for 1.99
Account balance after float operations: 8009,765625
Operations using BigDecimal:
1000 operations for 1.99
Account balance after BigDecimal operations: 8010,000000
開始時の残高が10000.00の場合、1.99の1000回の操作後、残高は8010.00になると予想しています。 float型を使用すると、8009.77付近の回答が得られますが、これは金銭計算の場合には容認できないほど不正確です。 BigDecimalを使用すると、適切な結果が得られます。
BigDecimal.valueOf()
BigDecimalクラスには、頻繁に使用される数値(0〜10など)の内部キャッシュが含まれます。BigDecimal.valueOf()メソッドは、類似した型パラメータを持つコンストラクタに優先して提供されます。
BigDecimal a = BigDecimal.valueOf(10L); //Returns cached Object reference
BigDecimal b = new BigDecimal(10L); //Does not return cached Object reference
BigDecimal a = BigDecimal.valueOf(20L); //Does not return cached Object reference
BigDecimal b = new BigDecimal(20L); //Does not return cached Object reference
BigDecimal a = BigDecimal.valueOf(15.15); //Preferred way to convert a double (or float) into a BigDecimal, as the value returned is equal to that resulting from constructing a BigDecimal from the result of using Double.toString(double)
BigDecimal b = new BigDecimal(15.15); //Return unpredictable result
BigDecimalの値ゼロ、1または10の初期化
BigDecimalは、ゼロ、1、および10の数の静的プロパティを提供します。実際の数値を使用する代わりに、これらを使用することをお勧めします。
静的なプロパティを使用することで、不要なインスタンス化を避けることができます。また、「マジックナンバー」の代わりにコード内にリテラルがあります。
//Bad example:
BigDecimal bad0 = new BigDecimal(0);
BigDecimal bad1 = new BigDecimal(1);
BigDecimal bad10 = new BigDecimal(10);
//Good Example:
BigDecimal good0 = BigDecimal.ZERO;
BigDecimal good1 = BigDecimal.ONE;
BigDecimal good10 = BigDecimal.TEN;