Java @ mock

BigDecimal

最終更新:

Bot(ページ名リンク)

- view
管理者のみ編集可

BigDecimal


Javaにおいてjava.math.BigDecimalクラスは固定小数点数を扱うクラスです。
浮動小数点数は2の乗数分の1を足して小数の計算をしますが、それでは誤差が発生してしまうことがあります。
固定小数点数だと、「整数値×10の乗数」として整数部の計算と小数点の位置の計算を分けて行うのでより正確な値が返ります。

ちなみにdecimalとは「小数」、「小数の」、「10進法の」などという意味だそうです。

BigDecimalのコンストラクタは以下のようなものがあります。
BigDecimal(BigInteger val) 
          BigIntegerをBigDecimalに変換します。
BigDecimal(BigInteger unscaledVal, [[int]] scale) 
          BigIntegerのスケールなしの値とintスケールをBigDecimalに変換します。
BigDecimal([[double]] val) 
          doubleをBigDecimalに変換します。
BigDecimal([[String]] val) 
          BigDecimalのString表現をBigDecimalに変換します。


BigDecimal 使用例 1

BigDecimalの基本的な計算を行うメソッドを使ってみます。
addメソッド:加算
multiplyメソッド:乗算
divideメソッド:除算

BigDecimalSample1.java
import java.math.BigDecimal;

class BigDecimalSample1 {
	
	public static void main(String[] args) {
		
		BigDecimal bigDecimalObject1 = new BigDecimal("0.5");
		BigDecimal bigDecimalObject2 = new BigDecimal("0.25");
		
		System.out.println("bigDecimalObject1\t:\t" + bigDecimalObject1);
		System.out.println("bigDecimalObject2\t:\t" + bigDecimalObject2);
		// add(BigDecimal val) メソッド:加算
		System.out.println("bigDecimal add\t\t:\t" + bigDecimalObject1.add(bigDecimalObject2));
		// multiply(BigDecimal val) メソッド:乗算
		System.out.println("bigDecimal multiply\t:\t" + bigDecimalObject1.multiply(bigDecimalObject2));
		// divide(BigDecimal val) メソッド:除算
		System.out.println("bigDecimal divide\t:\t" + bigDecimalObject1.divide(bigDecimalObject2));
	}
}

実行結果
C:\java>javac BigDecimalSample1.java

C:\java>java BigDecimalSample1
bigDecimalObject1       :       0.5
bigDecimalObject2       :       0.25
bigDecimal add          :       0.75
bigDecimal multiply     :       0.125
bigDecimal divide       :       2


BigDecimal 使用例 2 (divide)

上記のプログラムのbigDecimalObject2のデータの値を0.255などとするとdivideメソッドでjava.lang.ArithmeticExceptionが起こります。
ArithmeticExceptionは算術計算で例外的条件が発生した場合にスローされます。
これは丸めモードを指定していないためです。以下のメソッドを使うと正常に動作します。
divide(BigDecimal val, int roundingMode)
divide(BigDecimal val, int scale, int roundingMode)

scaleにはスケールを指定します。
roundingModeには丸めモードを指定します。

BigDecimalSample2.java
import java.math.BigDecimal;

class BigDecimalSample2 {
	
	public static void main(String[] args) {
		
		BigDecimal bigDecimalObject1 = new BigDecimal("0.5");
		BigDecimal bigDecimalObject2 = new BigDecimal("0.255");
		
		System.out.println("bigDecimalObject1\t:\t" + bigDecimalObject1);
		System.out.println("bigDecimalObject2\t:\t" + bigDecimalObject2);
		//  divide(BigDecimal val, int scale, RoundingMode roundingMode)
		System.out.println(
			"bigDecimal divide\t:\t" + bigDecimalObject1.divide(bigDecimalObject2, 3, BigDecimal.ROUND_HALF_UP));
		//  divide(BigDecimal val, int scale, RoundingMode roundingMode)
		System.out.println(
			"bigDecimal divide\t:\t" + bigDecimalObject1.divide(bigDecimalObject2, 7, BigDecimal.ROUND_HALF_UP));
	}
}

実行結果
C:\java>java BigDecimalSample2
bigDecimalObject1       :       0.5
bigDecimalObject2       :       0.255
bigDecimal divide       :       1.961
bigDecimal divide       :       1.9607843


スケール・丸めモード

固定小数点数の場合、「整数値×10の乗数」として整数部の計算と小数点の位置の計算を分けて行います。
スケールは10×-?乗の?のことです。
以下の場合「3」、「7」が各々のスケールになります。
1.961 = 1961 × 10の-3乗
1.9607843 = 19607843× 10の-7乗
丸めモードは丸め処理のモードを指定するものです。

BigDecimalのフィールドに丸めモードを指定するための定数が用意されています。
static int	ROUND_CEILING 
          正の無限大に近づくように丸めるモードです。
static int	ROUND_DOWN 
          0 に近づくように丸めるモードです。
static int	ROUND_FLOOR 
          負の無限大に近づくように丸めるモードです。
static int	ROUND_HALF_DOWN 
          「もっとも近い数字」 に丸めるモードです。
static int	ROUND_HALF_EVEN 
          「もっとも近い数字」 に丸めるモードです。
static int	ROUND_HALF_UP 
          「もっとも近い数字」に丸めるモードです。
static int	ROUND_UNNECESSARY 
          要求される演算の結果が正確であり、丸めが必要でないことを表す丸めモードです。
static int	ROUND_UP 
          0 から離れるように丸めるモードです。


ウィキ募集バナー