6
Pickman
6y

Today my boss sent me something that smelled fishy to me. While he was trying to simulate Excel's rounding he faced what was to him unexpected behaviour and he claimed that one constructor of the BigDecimal class was "wrong".
It took me a moment why this was happening to him and I identified two issues in his code.
I found one fo the issues funny and I would like to present you a challenge. Can you find a number that disproves his claim?
It's Java if anyone was wondering.

double d = 102.15250;

BigDecimal db = new BigDecimal(d)
.setScale(3, BigDecimal.ROUND_HALF_EVEN);

BigDecimal db2 = new BigDecimal(String.format("%f",d))
.setScale(3, BigDecimal.ROUND_HALF_EVEN);

BigDecimal db3 = BigDecimal.valueOf(d)
.setScale(3, BigDecimal.ROUND_HALF_EVEN);

System.out.println(db); // WRONG! 102.153
System.out.println(db2); // RIGHT! 102.152
System.out.println(db3); // RIGHT! 102.152

P.s. of course the code itself is just a simple check, it's not how he usually writes code.
P.p.s. it's all about the numerical representation types.

Comments
  • 0
    Does the BidDezimal consstructor only take floats?
  • 0
    No, of course. It's just the BigDecimal class, you can find the APIs online.
  • 0
    @filthyranter this is the root of the problem. Well done. But how to explain its manifestation? Why do the other two prints exhibit the correct behaviour? Do they do that always (they don't)? How do we find a number that shows this?

    Also notice how the author of this code was actually lazy and used BigDecimal to round the numbers instead if writing his own function.
  • 1
    This is like 0 != 0m in c#
  • 0
    @filthyranter not quite, the second two cast the double to float and then use the string representation of that float. This means that is equivalent to using the first constructor (well its version that takes a float) by casting the double to float. What's funny is that this does not prevent "unexpected" behaviour.

    In fact if that double would be a float there would not be this "error".
  • 0
    @gruff yes, I guess it is.
Add Comment