Reputation: 1392
I'm trying to simulate the ATM amount input in Java, ie. say the user keeps inputting "1", the amount shown should be:
0.00
0.01
0.11
1.11
11.11
111.11
I tried both Double and BigDecimal for processing:
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 )
However both seems to show this instead:
0.00
0.01
0.11
1.11
11.1 <<< missing the 0.01 at the end
111.01
are they both due to a precision rounding error (I thought BigDecimal does not have this problem) or am I doing something wrong?
Upvotes: 1
Views: 1317
Reputation: 4421
The simplest option might be to record the input as a String. After each key press append the new character to the end of it, and format the number by creating a BigDecimal and dividing it by 100.
String input = "111111";
BigDecimal value = new BigDecimal(input).divide(new BigDecimal(100)); // 1111.11
That said, I've just tried your code in a loop and it appears to work fine. You'll need to post the code showing how you generate 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
Upvotes: 2
Reputation: 164
Java BigDecimal has a constructor that takes a double and another that takes a string. You are using the double constructor, although the string constructor is usually recommended. Have you tried it?
BigDecimal addend = new BigDecimal("0.01");
For more information, see The Evil Big Decimal Constructor.
Upvotes: 1
Reputation: 28563
Why do you want to compute an amount on the fly? Just store the string as it comes and parse it at the end.
// 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));
}
Upvotes: 0
Reputation: 65879
It's easier to mess with the string:
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);
}
}
Here I remove the ".", add a "1", create a BigDecimal
from it and divide that by 100.
Upvotes: 0