number formatting

Possible Duplicate:
Why not use Double or Float to represent currency?

I'm learning Java so please bear with me for such a simple question. When given a calculation to calculate interest i have this code inputted:

 public double calculateTotal(double rate, int n)
 {
     amount = amount * Math.pow((1+rate), (n/12));
     return amount;
 }

This returns the answers I'm looking for but keeps adding 0.000000000001 onto the end. How would i solve this? A friend advised something called number formatting but i couldn't find a solution.


This problem is related to widely known floating point calculation issue.

One of the solutions could be use of import java.math.BigDecimal

  • Minimizing the effect of accuracy problems article describes the problem.
  • Take a look at this ticket Calculation problem in Java
  • EDIT

    Java does not allow to override operators so the only way to add BigDecimal s together is by using add method eg (assuming your amount is BigDecimal . Bear in mind that BigDecimal is immutable so whatever is returned from calculateTotal needs to be assigned back to ammount

    // you assign result to amount outside calculateTotal
    amount.add(new BigDecimal(Math.pow((1+rate), (n/12))));
    

    or

    // you assign sum to amount inside calculateTotal
    amount = amount.add(new BigDecimal(Math.pow((1+rate), (n/12))));
    

    As it was mentioned before BigDecimal is good option if you need better precision with doubles.

    There is nice way to do rounding with BigDecimal s. Basically you have to specify scale of the BigDecimal instance. Take a look at this sample code:

    BigDecimal decimalOne = new BigDecimal(0.1950);
    BigDecimal decimalTwo = decimalOne.setScale(2, BigDecimal.ROUND_HALF_DOWN);
    BigDecimal decimalThree = decimalOne.setScale(4, BigDecimal.ROUND_HALF_DOWN);
    
    System.out.println("decimalOne: " + decimalOne);
    System.out.println("decimalTwo: " + decimalTwo);
    System.out.println("decimalThree: " + decimalThree);
    

    Java 7 would print something like this:

    decimalOne: 0.195000000000000006661338147750939242541790008544921875
    decimalTwo: 0.20
    decimalThree: 0.1950
    

    Please note that BigDecimal instances are immutable and that's why you have to assign result of setScale to new instance ( decimalOne will not be changed).


    In many financial system double s are not used to store currency information; long type with specific precision is used instead eg for precision 2, value 100 would be 1.00 , 122 would be 1.22 etc. That approach simplifies and seeds up calculations but it is not good for all the systems. However for simplicity of that question I won't dive into that subject too much.

    链接地址: http://www.djcxy.com/p/85812.html

    上一篇: 使用double来临时存储货币值?

    下一篇: 数字格式