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 )