Java BigDecimal /双精度错误

时间:2014-06-10 16:04:33

标签: java double bigdecimal

我试图模拟Java中的ATM数量输入,即。假设用户继续输入" 1",显示的数量应为:

0.00
0.01
0.11
1.11
11.11
111.11

我尝试了Double和BigDecimal进行处理:

println( ((new BigDecimal(current)).multiply(new BigDecimal(10)).add(new BigDecimal(0.01))).setScale(2, RoundingMode.HALF_UP).toString()) )

println( "" + Double.parseString(current) * 10 + 0.01 )

然而,两者似乎都表明了这一点:

0.00
0.01
0.11
1.11
11.1 <<< missing the 0.01 at the end
111.01

它们都是由于精确舍入错误(我认为BigDecimal没有这个问题)或者我做错了什么?

4 个答案:

答案 0 :(得分:2)

最简单的选项可能是将输入记录为String。每次按键后,将新字符附加到其末尾,并通过创建BigDecimal并将其除以100来格式化数字。

String input = "111111";
BigDecimal value = new BigDecimal(input).divide(new BigDecimal(100)); // 1111.11

那就是说,我刚刚在循环中尝试了你的代码,它似乎工作正常。您需要发布显示如何生成current

的代码
String current = "0.00";
for (int i = 0; i < 10; i++) {
    current = (new BigDecimal(current).multiply(new BigDecimal(10)).add(new BigDecimal(0.01))).setScale(2, RoundingMode.HALF_UP).toString();
    System.out.println(current);
}

//    0.01
//    0.11
//    1.11
//    11.11
//    111.11
//    1111.11
//    11111.11
//    111111.11
//    1111111.11
//    11111111.11

答案 1 :(得分:1)

Java BigDecimal有一个构造函数,它接受一个double,另一个接受一个字符串。您正在使用双构造函数,尽管通常建议使用字符串构造函数。你试过吗?

BigDecimal addend = new BigDecimal("0.01");

有关详细信息,请参阅The Evil Big Decimal Constructor

答案 2 :(得分:0)

更容易弄乱字符串:

public void test() {
    String s = "0.00";
    for (int i = 0; i < 5; i++) {
        s = new BigDecimal(s.replaceAll(Pattern.quote("."), "") + "1").divide(ONEHUNDRED).toString();
        System.out.println(s);
    }
}

在这里,我删除“。”,添加“1”,从中创建BigDecimal并将其除以100。

答案 3 :(得分:0)

为什么要动态计算金额?只需将字符串存储起来并在最后解析它。

// Store user input as string (pseudo code)
String readUserInput() {
  String accumulator = "";
  while (user input available) {
    accumulator += user input;
  }
  return accumulator;
}

// Get user input as double
Double getAmount(String input) {
  return Double.parseDouble( input ) / 100.0;
}

// Or a BigDecimal too
BigDecimal getAmount(String input) {
  return new BigDecimal(input).divide(new BigDecimal(100));
}