2

切り上げと切り下げを行う簡単なコードがいくつかありますが、予期しない結果が発生しています。

    public static void main(String[] args) throws Exception {
    // TODO Auto-generated method stub

    double a = 46.66;
    System.out.println("Roundup: " + roundUp(a,2) + "\nRound Down: " + roundDown(a,2));

}

public static double roundUp(double a, int scale)
{
    BigDecimal value = new BigDecimal(a);
    value = value.setScale(scale, RoundingMode.UP);
    return value.doubleValue();
}

public static double roundDown(double a, int scale)
{
    BigDecimal value = new BigDecimal(a);
    value = value.setScale(scale, RoundingMode.DOWN);
    return value.doubleValue();
}

小数点以下3桁を使用すると、期待どおりに機能します。a = 44.661の場合、出力は次のようになります。

切り上げ:46.67切り下げ:46.66

a = 44.66の場合、切り捨て値は1減少しますが、これは以下のように予期しないことです。

切り上げ:46.66切り下げ:46.65

上記の結果を保持したまま、ラウンドダウンで44.66、ラウンドアップで44.67を取得するにはどうすればよいですか。

よろしくお願いします

4

3 に答える 3

9

これは、実際には BigDecimals を使用しておらず、double を使用しているためです。入力44.66すると double に変換され、44.66 よりわずかに小さい値になります。BigDecimal入力を与える前に既に発生した丸め誤差を修正することはできません。

代わりにこれを試してください。

public static void main(String[] args) throws Exception {
    BigDecimal a = new BigDecimal("46.66");
    System.out.println("Roundup: " + roundUp(a,2) + "\nRound Down: " + roundDown(a,2));
}

public static BigDecimal roundUp(BigDecimal a, int scale)
{
    return a.setScale(scale, RoundingMode.UP);
}

public static BigDecimal roundDown(BigDecimal a, int scale)
{
    return a.setScale(scale, RoundingMode.DOWN);
}
于 2012-08-17T17:37:31.810 に答える
2

できることは、 BigDecimal.valueOf を使用して切り上げまたは切り捨てです

 BigDecimal value = BigDecimal.valueOf(a);

これにより double の表現誤差が補正されますが、算術丸め誤差もある場合、これでは不十分な場合があります。

代わりに、最大の丸め誤差を特定する必要があります。

public static double roundUp2(double d) {
    return Math.ceil(d * 100 - ERR)/100.0;
}

public static double roundHalf2(double d) {
    return Math.ceil(d * 100)/100.0;
}

public static double roundDown2(double d) {
    return Math.floor(d * 100 + ERR)/100.0;
}
于 2012-08-17T19:54:13.277 に答える
0

本当に必要なのは、次のような機能を実行することだと思います。

private static void roundUp(double num, int decimalPlaces){

for (int i =0; i< decimalPlaces; ++i){
     num*=10; 
}

int tmp = (int) (num+0.5);
num = tmp;

for (int i =0; i< decimalPlaces; ++i){
     num = num/10; 
}
}

また、「num + 0.5」を「num - 0.5」に変更するだけで、切り捨てに別の方法を使用できます。ただし、マシンの浮動小数点数エラーのため、印刷時に問題が発生する可能性があります。しかし、あなたはそのために何かを解決することもできます.

于 2012-08-17T17:45:59.183 に答える