title: The Java BigDecimal vs The Financial Mans - "The 1 cent problem"
body: <p>I have this problem: <strong>The financial mans says: "Error of your programation"</strong>.</p>
  
  <p>The official table of values and final calc from financial is</p>
  
  <pre>
  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
  </pre>
  
  <p>My function's return value must match the total value from that table:</p>
  
  <pre><code>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 &lt; 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);
      }
  }
  </code></pre>
  
  <p>system out: 
  <code>
  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!</p>
  
  <p></code></p>
  
  <p>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:<br></p>
  
  <pre><code>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&lt;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&gt;=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);
  
  
      }
  
  }
  </code></pre>
  
  <p>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"..</p>
  
  <p>thanks for all!...</p>