BigDecimalのsetScale、メソッド名がいまいち
BigDecimalを使って「1000×0.01=10」を表現したかったんです。
初めに書いたコードがこれ。
BigDecimal a = new BigDecimal("1000"); BigDecimal b = new BigDecimal("0.01"); BigDecimal c = a.multiply(b); System.out.println(a + " * " + b + " = " + c);
結果は、
1000 * 0.01 = 10.00
10.00じゃなくて、10なんだよなー、と思い、次のように書き換えました。
BigDecimal a = new BigDecimal("1000"); BigDecimal b = new BigDecimal("0.01"); BigDecimal c = a.multiply(b); c.setScale(0, BigDecimal.ROUND_DOWN);
小数点以下は切り捨てでよかったので、setScaleでそのように指定。
しかし結果は、
1000 * 0.01 = 10.00
小数点以下の精度を設定したのに、なんで変わらないの・・・
頭がパニクって、わからん!とツイートしたら、こうしたらできるよ、と教えてもらいました。
BigDecimal a = new BigDecimal("1000"); BigDecimal b = new BigDecimal("0.01"); BigDecimal c = a.multiply(b).setScale(0, BigDecimal.ROUND_DOWN); System.out.println(a + " * " + b + " = " + c);
1000 * 0.01 = 10
おお!できた!
・・・んー・・何で1行でsetScaleすると大丈夫で、2行かけてsetScaleするとだめなの??
さらに頭が混乱してきました。
改めて setScaleのJavadoc を見ると、戻り値がBigDecimalになっている!
set〜〜とかいうメソッド名のせいで、戻り値はvoidか、あってもbooleanだろうと勝手に思い込んでしまってました。
(落ち着いて考えれば、戻りがvoidなら、1行で書いた時に左辺のcに何も入らず、コンパイルエラーになります。。)
Javadocの先頭を読むと、「変更が不可能な、任意精度の符号付き小数です。」とあるので、BigDecimalのインスタンスは不変オブジェクトなんですね。
だから、いったんインスタンスを作ってからの、scaleの変更などはできず、setScaleというメソッド名ながら、scaleを設定した新たなインスタンスを返すような仕様だったようです。
・・・だったら、名前もgetScaledInstanceとかにして欲しかったな〜
長いか。