正確な値 (特に金額、金利など) を扱う場合は、浮動小数点値や算術演算を避ける必要があります。浮動小数点変数は非常に広い範囲の値を取ることができますが、正確ではありません。特に、長期または非常に異なる数量を計算する場合は、問題が発生します。丸め誤差が累積する可能性があります。これは、10 進数の幅広い値の範囲が固定長の 32/64 ビットの 2 進数値に格納される方法が原因です。たとえば、無実のフレンドリーな値0.1
は、バイナリ浮動小数点値としては非常に困難です。詳細については、IEEE 754 仕様を参照してください。
したがって、これらの場合、正確な計算にはデータ型を使用する必要があります。Java はBigDecimalクラスを提供します。浮動小数点の精度エラーを回避する別のアプローチは、計算に整数のみを使用し、出力をフォーマットして特定の小数点以下の桁数にすることです。
しかし、Java には固定小数点演算 ( BigDecimal ) 用のすぐに使える優れたクラスが用意されているので、試してみてください。この小さなサンプル コード スニペットを見てください。いくつかの異なる丸めモードから選択して、必要な小数点以下の桁数を決定できます。
import java.math.BigDecimal;
import java.math.RoundingMode;
public class RoundTest {
public static void main(String[] args) {
String userInput = "42.133742";
BigDecimal startValue = new BigDecimal(userInput);
BigDecimal multFactor = new BigDecimal("1.23"); // => increase by 23 %
BigDecimal result = startValue.multiply(multFactor);
System.out.println("Original result without rounding: " + result);
System.out.println("Scale: " + result.scale());
// Compare different rounding modes:
final int DECIMAL_PLACES = 2;
BigDecimal roundDown = result.setScale(DECIMAL_PLACES, RoundingMode.DOWN);
BigDecimal roundHalfUp = result.setScale(DECIMAL_PLACES, RoundingMode.HALF_UP);
BigDecimal roundUp = result.setScale(DECIMAL_PLACES, RoundingMode.UP);
System.out.println("Round down (" + DECIMAL_PLACES + " decimal places): " + roundDown);
System.out.println("Round half-up (" + DECIMAL_PLACES + " dec. places): " + roundHalfUp);
System.out.println("Round up (" + DECIMAL_PLACES + " decimal places): " + roundUp);
}
}