小数点以下を四捨五入する(BigDecimal)
事務処理計算で小数点を扱う場合、浮動小数点である基本型より、BigDecimal
classが適しています。
BigDecimalの小数点以下の丸めを行うには、割り算で丸めを行うか、setScale
methodで丸めるかの2つがあります。
ここでは特にrounding mode(丸めモード)に注目しています。
import java.math.*;
public class ExamRoundBigDecimal {
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal("110");
BigDecimal bd2 = new BigDecimal("0.05");
BigDecimal bd3 = bd1.multiply(bd2);
System.out.println("110 * 0.05 = " + bd3);
System.out.println( bd3.setScale(0,BigDecimal.ROUND_HALF_UP));
System.out.println( bd3.setScale(0,BigDecimal.ROUND_HALF_DOWN));
BigDecimal bd4 = new BigDecimal("17.2");
BigDecimal bd5 = new BigDecimal("5");
BigDecimal bd6 = bd4.divide(bd5, 1, BigDecimal.ROUND_HALF_UP);
System.out.println("17.2 / 5 = " + bd6);
BigDecimal bd7 = new BigDecimal("5.25");
BigDecimal bd8 = new BigDecimal("5.35");
BigDecimal bd9 = new BigDecimal("5.45");
System.out.println( "5.25 = " + bd7.setScale(1,BigDecimal.ROUND_HALF_EVEN));
System.out.println( "5.35 = " + bd8.setScale(1,BigDecimal.ROUND_HALF_EVEN));
System.out.println( "5.45 = " + bd9.setScale(1,BigDecimal.ROUND_HALF_EVEN));
}
}
<実行結果>
コンソール画面に
110 * 0.05 = 5.50
6
5
17.2 / 5 = 3.4
5.25 = 5.2
5.35 = 5.4
5.45 = 5.4
と表示されます。
<setScale method>
第1引数 : 小数点以下の桁数。( scale
)
第2引数 : 丸めモード。( rounding mode)
1番目は5.5を丸めています。rounding modeがROUND_HALF_UPであれば、5,5
-> 6
ROUND_HALF_DOWNであれば、5.5 -> 5になります。
つまりROUND_HALF_UPは、丸めの対象になる桁が5以上であれば、切り上げ、5未満は切り捨てされ、四捨五入に当たります。
ROUND_HALF_DOWNは、丸めの対象になる桁が5以下は切り捨て、それ以上は切り上げされます。
2番目は 17.2 / 5 = 3.44 を丸めています。
ROUND_HALF_UPを使うと丸め対象になる桁が4であれば、切り捨てられていることがわかります。
3番目はROUND_HALF_EVENの検証です。5.25 ->
5.2 , 5.35 -> 5.4 , 5.45 -> 5.4
丸め対象になる桁が5である時、結果が偶数になるように丸めています。
つまり5,25 は 5.2と5,3が等距離にありますから、結果が偶数になるように、5,2となります。
同じく5.35 は 5.3と5.4が等距離にありますから、結果が偶数になるように、5.4となります。
同様に5.45は5.4と5.5が等距離にありますから、5.4になります。
これmodeは丸められた数値を累積した時に、丸め誤差を最小にすることが出来ます。
この例では、5.25+5.35+5.45=16.05 ですが、四捨五入で丸めた場合は、5.3+5.4+5.5=16.2
になります。
ROUND_HALF_EVENで丸めた場合は、5.2+5.4+5.4=16.0となります。
誤差は、16.2-16.05=0.15 , 16.0-16.05=-0.05
となります。