<目的>
(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); }