<目的>
(1) JavaのBigDecimalの使い方+初期化や四則演算・桁数設定等の主要用途も紹介
(1-1) 宣言の方法
(1-2) 代表的な用途(足し算・引き算・掛け算・割り算)
(1-3) 代表的な用途(余り・累乗)
(1-4) 複数の計算を1行に書く方法
(2) BigDecimalの効果の確認
(2-1) double型の例(誤差あり)
(2-2) BigDecimal型の例(誤差ほぼなし)
(1) JavaのBigDecimalの使い方+初期化や四則演算・桁数設定等の主要用途も紹介
(1-1) 宣言の方法
BigDecimal型を生成するには「valueOf()」メソッドを使うか、コンストラクタを使います。
//①valueOfメソッド
BigDecimal bigdecimal1 = BigDecimal.valueOf(99.9);
//②コンストラクタ
BigDecimal bigdecimal2 = new BigDecimal("99.9");
ちなみに、コンストラクタに直接小数点の数字を代入してしまうとdouble型の誤差が発生する事があるため、やはりString型で指定する必要があります。
//【NG例】↓double型の誤差が残ってしまう BigDecimal bigdecimal3 = new BigDecimal(99.9);
(1-2) 代表的な用途(足し算・引き算・掛け算・割り算)
四則演算のサンプルプログラムです。
package studyc;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class IT0128_BigDecimal_Basic {
public static void main(String[] args) {
//BigDecimal型の変数(インスタンス)を初期化
BigDecimal bd1 = BigDecimal.valueOf(9);
BigDecimal bd2 = BigDecimal.valueOf(4);
//上から順に、足し算・引き算・掛け算・割り算
// 足し算:bd1 + bd2 = 9 + 4 = 13
BigDecimal add = bd1.add(bd2);
// 引き算:bd1 - bd2 = 9 - 4 = 5
BigDecimal sub = bd1.subtract(bd2);
// 掛け算:bd1 * bd2 = 9 * 4 = 36
BigDecimal mul = bd1.multiply(bd2);
// 割り算:bd1 / bd2 = 9 / 4 = 2
// ・第1引数は「割る数」
// ・第2引数は「小数点以下の桁数」
// ・第3引数は「端数処理方法」
// ・「java.math.RoundingMode」クラスのインポートが必要
BigDecimal div = bd1.divide(bd2,20,RoundingMode.HALF_UP);
System.out.println("add="+add+"\t sub="+sub+"\t mul="+mul+"\t div="+div);
}
}
(図121)

(1-3) 代表的な用途(余り、累乗)
余りと累乗のサンプルプログラムです。
import java.math.BigDecimal;
public class IT0128_BigDecimal_Basic3 {
public static void main(String[] args) {
//BigDecimal型の変数(インスタンス)を初期化
BigDecimal bd1 = BigDecimal.valueOf(9);
BigDecimal bd2 = BigDecimal.valueOf(4);
//割った余り
BigDecimal rem = bd1.remainder(bd2);
//累乗
BigDecimal pow = bd1.pow(2);
System.out.println("rem="+rem+"\t pow="+pow);
}
}
(図131)

(1-4) 複数の計算を1行に書く方法
複数の計算を1行にまとめて書く方法です。add()やmultiply()等の演算の後ろにドット「.」で繋げて「add().multiply()」のようにして、次の演算を連続して記述する事ができます。
// 2行に分けて記述 BigDecimal tmp = bd1.add(bd2); BigDecimal res1 = tmp.multiply(bd2); // 1行にまとめて記述 BigDecimal res2 = bd1.add(bd2).multiply(bd2);
(サンプルプログラム)
import java.math.BigDecimal;
public class IT0128_BigDecimal_Basic4 {
public static void main(String[] args) {
//BigDecimal型の変数(インスタンス)を初期化
BigDecimal bd1 = BigDecimal.valueOf(2);
BigDecimal bd2 = BigDecimal.valueOf(3);
// 2行に分けて記述
BigDecimal tmp = bd1.add(bd2);
BigDecimal res1 = tmp.multiply(bd2);
System.out.println("res1="+res1);
// 1行にまとめて記述
BigDecimal res2 = bd1.add(bd2).multiply(bd2);
System.out.println("res2="+res2);
}
}
(図141)

(2) BigDecimalの効果の確認
実際にBigDecimalの効果を体感するために、一つ簡単な例を見てみます。
(図211)

(サンプルPG)
import java.math.BigDecimal;
import java.math.RoundingMode;
public class IT0128_BigDecimal_Basic2 {
public static void main(String[] args) {
System.out.println("結果1_double型の計算:\t\t"+calc1());
System.out.println("結果2_BigDecimal型の計算:\t"+calc2());
}
public static double calc1() {
double a = 10.0;
double b = 154.0;
return a / b * b;
}
public static BigDecimal calc2() {
BigDecimal a = new BigDecimal("10.0");
BigDecimal b = new BigDecimal("154");
return a.divide(b,70,RoundingMode.HALF_UP).multiply(b);
}
}
(2-1) double型の例(誤差あり)
上図の「calc1()」メソッドは、double型で近似値の影響による誤差が発生している例です。double型の「10.0」を同じdouble型の「154.0」で割ってから、再度「154.0」を掛け算しても、元の値(10.0)には戻らずに「9.999999999999998」になってしまいます(小数第15位で誤差)。
public static double calc1() {
double a = 10.0;
double b = 154.0;
return a / b * b;
}
(2-2) BigDecimal型の例(誤差ほぼなし)
上図の「calc2()」メソッドは、calc1()をBigDecimal型に置き換えて実装した例です。割り算(divide)では70桁の精度で計算するよう指定し、端数処理はHALF_UP(四捨五入)を指定しています。結果としては指定した桁数(70)までは誤差なく計算しています。
public static BigDecimal calc2() {
BigDecimal a = new BigDecimal("10.0");
BigDecimal b = new BigDecimal("154");
return a.divide(b,70,RoundingMode.HALF_UP).multiply(b);
}