2013-01-14 65 views
0

我有以下要求四捨五入金額:如何解決這個舍入要求?

1.2448 -> 1.25 
3.349 -> 3.35 
0.474 -> 0.47 

我曾嘗試BigDecimal的所有可能的模式。 setScale(2,RoundingMode。)方法,沒有任何成功。結果如下:

UP:  1.25, 3.35, 0.48 
HALF_UP: 1.24, 3.35, 0.47 
CEILING: 1.25, 3.35, 0.48 
FLOOR:  1.24, 3.34, 0.47 
DOWN:  1.24, 3.34, 0.47 
HALF_DOWN: 1.24, 3.35, 0.47 
HALF_EVEN: 1.24, 3.35, 0.47 

我也嘗試過使用BigDecimal.round(),結果也不好。

我怎樣才能以所需的方式四捨五入?

編輯:

爲什麼我確實需要一輪這種看似怪異的方式嗎?

在我們正在開發一個新的軟件,我們需要重現舍入行爲或遺留軟件(這是做生意的方式都想四捨五入做)

解決方案:

我絕對要在我的所有計算中保留BigDecimals。

所以,最後我想出了這個簡單的功能做了「漸進式」四捨五入:

public static BigDecimal roundAmount(BigDecimal amount) { 
    for (int i = amount.scale(); i >= 2; i--) { 
     amount = amount.setScale(i, RoundingMode.HALF_UP); 
    } 
    return amount; 
} 
+0

第一個例子看起來奇怪,究竟你需要? – zch

+0

你確定第二排嗎?在我看來,第一個值不是你所顯示的或舍入不是以這種方式發生 –

+2

爲什麼1.2448變爲1.25? – JasonD

回答

1

你想要做的是逐步舍入每個數字。 1.2448→1.245→1.25。

這意味着需要四捨五入的最小數字是.nn4444444444444445,它接近1/18縮放後加1/2 - 4/9。

每當我看到有人提出這個建議時,它是不正確的,但它很容易計算。

for (double d : new double[]{1.2448, 3.349, 0.474}) { 
    double rounded = Math.round(d * 1e2 + 1.0/18)/1e2; 
    System.out.printf("%s should be %.2f rounded half up and is %s%n", d, d, rounded); 
} 

打印

1.2448 should be 1.24 rounded half up and is 1.25 
3.349 should be 3.35 rounded half up and is 3.35 
0.474 should be 0.47 rounded half up and is 0.47 

正如你所看到的,需要添加1/18是奇數,但是這是當你圓每一個數字了逐步您實際上做什麼。

+2

他需要0.474 - > 0.47 – Suranga

+0

@guess_me我應該計算出差異而不是猜測。 ;) –

6

使用HALF_UP但首輪到小數點後三位,然後再以2的問題是,您所需的舍入顯示不一致的邏輯,因爲1.2448小於1.245,所以通常會舍入。但是先到達3個位置將使其達到1.245,然後將達到1.25。

0
public static void main(String[] args) { 
    double a = 0.474; 

    NumberFormat df = DecimalFormat.getInstance(); 
    df.setMinimumFractionDigits(2); 
    df.setMaximumFractionDigits(3); 
    df.setRoundingMode(RoundingMode.HALF_UP); 

    double b = Double.valueOf(df.format(a)); 
    NumberFormat dff = DecimalFormat.getInstance(); 
    dff.setMaximumFractionDigits(2); 
    dff.setRoundingMode(RoundingMode.HALF_UP); 

    System.out.println(dff.format(b)); 

} 

試試這個。

+1

'0.474'給​​出了'0.48',而他想要'0.47'。 – sp00m

+0

@ sp00m我糾正了這個錯誤。謝謝 –

1

herethere

public static double iterativeRound(double d, int scale) { 
    int currentScale = new BigDecimal(String.valueOf(d)).scale(); 
    while (currentScale >= scale) { 
     double i = Math.pow(10, currentScale--); 
     d = Math.round(d * i)/i; 
    } 
    return d; 
} 

例如:

System.out.println(iterativeRound(1.2448, 2)); 
System.out.println(iterativeRound(3.349, 2)); 
System.out.println(iterativeRound(0.474, 2)); 

打印:(尤指第三)

1.25 
3.35 
0.47