1

I have this problem: The financial mans says: "Error of your programation".

The official table of values and final calc from financial is

base        %              total value
667.63   -  1.5(0.015)   = 657.62
705.98   -  1.5(0.015)   = 695.39
687.77   -  1.5(0.015)   = 677.45
844.62   -  1.5(0.015)   = 831.95
743.23   -  1.5(0.015)   = 732.08
775.15   -  1.5(0.015)   = 763.52
874.82   -  1.5(0.015)   = 861.70
949.63   -  1.5(0.015)   = 935.39
987.18   -  1.5(0.015)   = 972.37
1040.28  -  1.5(0.015)   = 1024.68
1077.70  -  1.5(0.015)   = 1061.54
995.68   -  1.5(0.015)   = 980.74
1280.55  -  1.5(0.015)   = 1261.35
1140.56  -  1.5(0.015)   = 1123.45
653.23   -  1.5(0.015)   = 643.43
847.49   -  1.5(0.015)   = 834.78
995.68   -  1.5(0.015)   = 980.74

My function's return value must match the total value from that table:

public static void main(String[] args) {
    BigDecimal[] valorbase= {
        new BigDecimal("667.63"),
        new BigDecimal("705.98"),
        new BigDecimal("687.77"),
        new BigDecimal("844.62"),
        new BigDecimal("743.23"),
        new BigDecimal("775.15"),
        new BigDecimal("874.82"),
        new BigDecimal("949.63"),
        new BigDecimal("987.18"),
        new BigDecimal("1040.28"),
        new BigDecimal("1077.70"),
        new BigDecimal("995.68"),
        new BigDecimal("1280.55"),
        new BigDecimal("1140.56"),
        new BigDecimal("653.23"),
        new BigDecimal("847.49"),
        new BigDecimal("995.68")    
    };

    for (int i = 0; i < valorbase.length; i++) {
        BigDecimal desconto=new BigDecimal("0.015");
        BigDecimal valor_a_descontar=valorbase[i].multiply(desconto);

            valor_a_descontar=valor_a_descontar.setScale(2,RoundingMode.HALF_UP);
    //desconto=desconto.setScale(2,RoundingMode.HALF_UP);


    BigDecimal valortotal=valorbase[i].subtract(valor_a_descontar);
    valortotal.setScale(3,RoundingMode.HALF_UP);
    valortotal.setScale(2,RoundingMode.HALF_UP);

        System.out.println("BASE=" + valorbase[i] + " - descount=" + valor_a_descontar + " totalvalue=" + valortotal);
    }
}

system out: BASE=1077.70 - descount=16.17 totalvalue=1061.53 missing value of table! BASE=1280.55 - descount=19.21 totalvalue=1261.34 missing value of table!

The diff in some case is 0,01 cent but to financial it's impossible becouse this universe of people is 18.340 registry's the diff is 18340 x 0.01 x 365 x 2 = 4401,6 ===> R$ 4401,6 this the cost of one cent not rounded correctly! Can anyone help me? thanks JAY... This was proposed by JAY:

public static void main(String[] args){
    BigDecimal[] valorbase= {
            new BigDecimal("667.63"),
            new BigDecimal("705.98"),
            new BigDecimal("687.77"),
            new BigDecimal("844.62"),
            new BigDecimal("743.23"),
            new BigDecimal("775.15"),
            new BigDecimal("874.82"),
            new BigDecimal("949.63"),
            new BigDecimal("987.18"),
            new BigDecimal("1040.28"),
            new BigDecimal("1077.70"),
            new BigDecimal("995.68"),
            new BigDecimal("1280.55"),
            new BigDecimal("1140.56"),
            new BigDecimal("653.23"),
            new BigDecimal("847.49"),
            new BigDecimal("995.68")                

            };




    for(int i=0;i<valorbase.length;i++){

    BigDecimal desconto=new BigDecimal("0.985");

    //BigDecimal valor_a_descontar=valorbase[i].multiply(desconto);




    //valor_a_descontar=valor_a_descontar.setScale(2,RoundingMode.HALF_UP);
    //desconto=desconto.setScale(2,RoundingMode.HALF_UP);


    //BigDecimal valortotal=valorbase[i].subtract(valor_a_descontar);
    BigDecimal valortotal=valorbase[i].multiply(desconto);

    //valortotal.setScale(3,RoundingMode.HALF_UP);
    //valortotal.setScale(2,RoundingMode.HALF_EVEN);

    System.out.println("subtotal="+valortotal);

    if(valorbase[i].doubleValue()/1000>=1){
        valortotal=valortotal.setScale(8,RoundingMode.HALF_UP);
        valortotal=valortotal.setScale(7,RoundingMode.HALF_UP);
        valortotal=valortotal.setScale(6,RoundingMode.HALF_UP);
        valortotal=valortotal.setScale(5,RoundingMode.HALF_UP);
        valortotal=valortotal.setScale(4,RoundingMode.HALF_UP);
        valortotal=valortotal.setScale(3,RoundingMode.HALF_UP);
        valortotal=valortotal.setScale(2,RoundingMode.HALF_UP);
    }else{
        valortotal=valortotal.setScale(2,RoundingMode.HALF_UP);
    }       
    System.out.println("BASE="+valorbase[i]+" totalvalue="+valortotal);


    }

}

based on the Idea of Jay i make some modifications the financial guys says: "well, we never can uP de discount to clients..we need some times round the due to up on cent"..

thanks for all!...

4

2 回答 2

3

您确定您使用的是适当的RoundingMode吗?RoundingMode 1 是ROUND_DOWNRoundingMode 5 是ROUND_HALF_DOWN。也许您应该使用ROUND_HALF_EVEN(这在某些金融场景中很常见)?

此外,如果您使用这些枚举常量而不是方法,代码会更清晰RoundingMode.valueOf

于 2010-02-09T21:25:08.680 回答
1

您总是会遇到有关此类问题的确切舍入规则的问题。

比如,我们是在减法之前还是之后四舍五入。另外,您可能会说,作为一种捷径,1.5%的折扣与我们收取正常价格的98.5%相同,因此我们应该可以将原价乘以98.5%,而不必做额外的减法. 正确的?

假设价格为 667.00。

方法 1:667.00 * .015 = 10.005,向上取整到 10.01。那么 667.00 - 10.01 = 656.99。

方法 2:667.00 * .015 = 10.005。667.00 - 10.005 = 656.995。向上取整至 657.00。不同的答案。

方法 3:667.00 * .985 = 656.995,向上取整到 657.00。

此外,Roney 提到该表对于 1077.70 是错误的。1280.55 也是错误的。

于 2010-02-09T22:30:29.280 回答