気付かなかったりして、結構困る&ハマります(;´Д`)
まあ、ちゃんとテストすれば、気付くことではあるのですが。
正と負でそれぞれ四捨五入をしてみる
とりあえず、何も考えず、四捨五入をしてみます。
1 2 3 4 5 6 7 8 | public class DoubleTest { public static void main(String[] args) { System.out.println("11.5 : " + Math.round(11.5)); System.out.println("12.5 : " + Math.round(12.5)); System.out.println("-11.5 : " + Math.round(-11.5)); System.out.println("-12.5 : " + Math.round(-12.5)); } } |
実行結果
1 2 3 4 | 11.5 : 12 12.5 : 13 -11.5 : -11 -12.5 : -12 |
ん~、少し期待していた結果と違います。
冷静に考えれば、なんてことはないのですが。。つまり、常に正の無限大に向かって、四捨五入は行われます。
数学的に考えれば、これは正しいことなのですが・・、多くの場合、これは困ったことになります。
コンピュータで計算することといえば、お金の計算は、避けて通れません。
これは、お金を貰ったときとお金を返すときで、違う金額を計算してしまう可能性を示しています。
回避方法
BigDecimalを使いましょう。これだけで解決です。
1 2 3 4 5 6 7 8 9 10 11 | import java.math.BigDecimal; import java.math.RoundingMode; public class DoubleTest { public static void main(String[] args) { System.out.println("11.5 : "+new BigDecimal(11.5).setScale(0,RoundingMode.HALF_UP)); System.out.println("12.5 : "+new BigDecimal(12.5).setScale(0,RoundingMode.HALF_UP)); System.out.println("-11.5 : "+new BigDecimal(-11.5).setScale(0,RoundingMode.HALF_UP)); System.out.println("-12.5 : "+new BigDecimal(-12.5).setScale(0,RoundingMode.HALF_UP)); } } |
BigDecimalを使うことで、符号を反転すると、正と負で同じ結果が得られます。
BigDecimalで丸めを行う場合は、HALF_UP/HALF_DOWN/HALF_EVENの各モードがあるので気付くと思いますが、他の言語で四捨五入をするときは、「銀行丸め(偶数丸め)」なるものにも注意が必要です。(場合によっては、銀行丸めがデフォルトの場合もあります)