关于java:数字格式

number formatting

本问题已经有最佳答案,请猛点这里访问。

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

我正在学习Java,所以请为我简单的问题。当计算利息时,我输入此代码:

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

这将返回我要查找的答案,但会在结尾处不断添加0.00000000001。我该如何解决这个问题?一个朋友建议了一种叫做数字格式化的方法,但我找不到解决方案。


如前所述,如果您需要更好的精度和双打,BigDecimal是很好的选择。

使用BigDecimals进行舍入的方法很好。基本上,您必须指定BigDecimal实例的比例。看看这个示例代码:

1
2
3
4
5
6
7
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会打印这样的东西:

1
2
3
decimalOne: 0.195000000000000006661338147750939242541790008544921875
decimalTwo: 0.20
decimalThree: 0.1950

请注意,BigDecimal实例是不可变的,因此您必须将setScale的结果分配给新实例(decimalOne不会更改)。

在许多金融系统中,double不用于存储货币信息,而是使用具有特定精度的long类型,例如,对于精度2,值100将是1.00122将是1.22等,这种方法简化了计算并增加了种子,但对所有系统都不好。然而,为了这个问题的简单性,我不会太深入地探讨那个问题。


这个问题与众所周知的浮点计算问题有关。

其中一个解决方案是使用import java.math.BigDecimal

  • 文章描述了如何将精度问题的影响降到最低问题。
  • 查看Java中的票价计算问题

编辑

Java不允许覆盖运算符,因此唯一的方法是使用EDCOX1×2的方法来添加EDCOX1和1个集合。(假设您的量是EDCOX1×1)。记住bigdecimal是不可变的,所以从calculateTotal返回的内容需要分配回ammount

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

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