Java BigDecimal与The Financial Mans - “1美分问题” [英] The Java BigDecimal vs The Financial Mans - "The 1 cent problem"

查看:215
本文介绍了Java BigDecimal与The Financial Mans - “1美分问题”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个问题:财务人员说:您的程序错误

官方的价值表和最终计算方法来自金融是

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

我的函数的返回值必须与tha的总值相匹配t table:

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);
    }
}

系统输出:

BASE = 1077.70 - descount = 16.17 totalvalue = 1061.53缺少表的值!
BASE = 1280.55 - descount = 19.21 totalvalue = 1261.34缺少表格值!

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!

在某些情况下差异为0.01美分,但对于金融而言,这是不可能的因为这个人的世界是18.340注册表的差异是18340 x 0.01 x 365 x 2 = 4401,6 ===> R $ 4401 ,6这一分钱的成本没有正确舍入!谁能帮我?
谢谢JAY ...
这是由JAY提出的:

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"..

感谢所有人!...

推荐答案

你确定你是使用适当的 RoundingMode ? RoundingMode 1是 ROUND_DOWN ,而RoundingMode 5是 ROUND_HALF_DOWN 。也许您应该使用 ROUND_HALF_EVEN (这在某些财务方案中很常见)?

Are you sure that you are using the appropriate RoundingMode? RoundingMode 1 is ROUND_DOWN and RoundingMode 5 is ROUND_HALF_DOWN. Perhaps you are supposed to use ROUND_HALF_EVEN (which is common in some financial scenarios)?

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

Also, the code would be clearer if you used these enum constants instead of the RoundingMode.valueOf method.

这篇关于Java BigDecimal与The Financial Mans - “1美分问题”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆