BigDecimalの仕組みを利用してみた。

BigDecimalを利用するコードを書いてみました。
この記事でやっていることは、BigDecimalの仕組みを図解してみた。で図解した内容に基づいています。

目次

  • 基本的な構造
  • スケールを変える
  • 足し算
  • 引き算
  • 掛け算
  • 割り算

基本的な構造

基本的な構造を表示するためのメソッドを作りました。
表示形式は「実際の値 = 整数部 * 10 ^ ( - スケール )」です。

// BigDecimalについて詳しく表示する。
public static void printBigDecimal( String msg, BigDecimal val ) {
	// 整数部を取得する。
	BigInteger intValue = val.unscaledValue();
	// スケール
	int scale = val.scale();
	// 「実際の値 = 整数部 * 10 ^ ( - スケール )」の形式で表示する。
	System.out.println( msg + ": " + val + " = " + intValue + " * 10 ^ ( - " + scale + " )" );
}

(例) 1.234の構造を表示する。

printBigDecimal( "基本的な構造", b1 );
基本的な構造: 1.234 = 1234 * 10 ^ ( - 3 )

スケールを変える

スケールを増やす

(例) 2.5のスケールを2に変える。

b1 = new BigDecimal( "2.5" );

// スケールを2に変える。
b2 = b1.setScale( 2 );
スケール変更前: 2.5 = 25 * 10 ^ ( - 1 )

スケール変更後: 2.50 = 250 * 10 ^ ( - 2 )
スケールを減らす

(例) 2.50のスケールを1に変える。

b1 = new BigDecimal( "2.50" );

// スケールを1に変える。
b2 = b1.setScale( 1 );
スケール変更前: 2.50 = 250 * 10 ^ ( - 2 )

スケール変更後: 2.5 = 25 * 10 ^ ( - 1 )
スケールを減らす(丸め処理が必要)

(例) 2.5のスケールを0に変える。(切り捨て)

b1 = new BigDecimal( "2.5" );

// スケールを0に変える(切り捨て)。
b2 = b1.setScale( 0, BigDecimal.ROUND_DOWN );
スケール変更前: 2.5 = 25 * 10 ^ ( - 1 )

スケール変更後: 2 = 2 * 10 ^ ( - 0 )


(例) 2.5のスケールを0に変える。(切り上げ)
b1 = new BigDecimal( "2.5" );

// スケールを0に変える。(切り上げ)
b2 = b1.setScale( 0, BigDecimal.ROUND_UP );
スケール変更前: 2.5 = 25 * 10 ^ ( - 1 )

スケール変更後: 3 = 3 * 10 ^ ( - 0 )


(例) 2.5のスケールを0に変える。(丸めモード指定漏れ)
b1 = new BigDecimal( "2.5" );

// スケールを0に変える。(丸めモード指定漏れ)
b2 = b1.setScale( 0 );
スケール変更前: 2.5 = 25 * 10 ^ ( - 1 )

java.lang.ArithmeticException: Rounding necessary
	at java.math.BigDecimal.divide(BigDecimal.java:1346)
	at java.math.BigDecimal.setScale(BigDecimal.java:2310)
	at java.math.BigDecimal.setScale(BigDecimal.java:2350)
	at BigDecimalSample.main(BigDecimalSample.java:74)

足し算

(例) 12.3 + 0.29 = 12.59

b1 = new BigDecimal( "12.3" );
b2 = new BigDecimal( "0.29" );

// 足し算する。
b3 = b1.add( b2 );
足す数1: 12.3 = 123 * 10 ^ ( - 1 )
足す数2: 0.29 = 29 * 10 ^ ( - 2 )

足し算の結果: 12.59 = 1259 * 10 ^ ( - 2 )

引き算

(例) -2.74 − 14 = -16.74

b1 = new BigDecimal( "-2.74" );
b2 = new BigDecimal( "14" );

// 引き算する。
b3 = b1.subtract( b2 );
引かれる数: -2.74 = -274 * 10 ^ ( - 2 )
引く数: 14 = 14 * 10 ^ ( - 0 )

引き算の結果: -16.74 = -1674 * 10 ^ ( - 2 )

掛け算

(例) 0.012 × 2.3 = 0.0276

b1 = new BigDecimal( "0.012" );
b2 = new BigDecimal( "2.3" );

// 掛け算する。
b3 = b1.multiply( b2 );
掛ける数1: 0.012 = 12 * 10 ^ ( - 3 )
掛ける数2: 2.3 = 23 * 10 ^ ( - 1 )

掛け算の結果: 0.0276 = 276 * 10 ^ ( - 4 )

割り算

(例) 1.75 ÷ 6 = 0.292 (計算結果のスケールは3、丸めモードは切り上げ)

b1 = new BigDecimal( "1.75" );
b2 = new BigDecimal( "6" );

// 割り算する。(計算結果のスケールは3、丸めモードは切り上げ)
b3 = b1.divide( b2, 3, BigDecimal.ROUND_UP );
割られる数: 1.75 = 175 * 10 ^ ( - 2 )
割る数: 6 = 6 * 10 ^ ( - 0 )

割り算の結果: 0.292 = 292 * 10 ^ ( - 3 )


(例) 1.75 ÷ 6 = 0.291 (計算結果のスケールは3、丸めモードは切り捨て)
b1 = new BigDecimal( "1.75" );
b2 = new BigDecimal( "6" );

// 割り算する。(計算結果のスケールは3、丸めモードは切り捨て)
b3 = b1.divide( b2, 3, BigDecimal.ROUND_DOWN );
割られる数: 1.75 = 175 * 10 ^ ( - 2 )
割る数: 6 = 6 * 10 ^ ( - 0 )

割り算の結果: 0.291 = 291 * 10 ^ ( - 3 )


(例) 1.75 ÷ 6 = エラー (計算結果のスケールは3、丸めモードは丸め不要)
b1 = new BigDecimal( "1.75" );
b2 = new BigDecimal( "6" );

// 割り算する。(計算結果のスケールは3、丸めモードは丸め不要)
b3 = b1.divide( b2, 3, BigDecimal.ROUND_UNNECESSARY );
割られる数: 1.75 = 175 * 10 ^ ( - 2 )
割る数: 6 = 6 * 10 ^ ( - 0 )

java.lang.ArithmeticException: Rounding necessary
	at java.math.BigDecimal.divide(BigDecimal.java:1346)
	at BigDecimalSample.main(BigDecimalSample.java:162)


(例) 1.75 ÷ 6 = 0.30 (計算結果のスケールは「割られる数のスケール」と同じ、丸めモードは切り上げ)
b1 = new BigDecimal( "1.75" );
b2 = new BigDecimal( "6" );

// 割り算する。(計算結果のスケールは「割られる数のスケール」と同じ、丸めモードは切り上げ)
b3 = b1.divide( b2, BigDecimal.ROUND_UP );
割られる数: 1.75 = 175 * 10 ^ ( - 2 )
割る数: 6 = 6 * 10 ^ ( - 0 )

割り算の結果: 0.30 = 30 * 10 ^ ( - 2 )


(例) 1.75 ÷ 6 = 0.29 (計算結果のスケールは「割られる数のスケール」と同じ、丸めモードは切り捨て)
b1 = new BigDecimal( "1.75" );
b2 = new BigDecimal( "6" );

// 割り算する。(計算結果のスケールは「割られる数のスケール」と同じ、丸めモードは切り捨て)
b3 = b1.divide( b2, BigDecimal.ROUND_DOWN );
割られる数: 1.75 = 175 * 10 ^ ( - 2 )
割る数: 6 = 6 * 10 ^ ( - 0 )

割り算の結果: 0.29 = 29 * 10 ^ ( - 2 )