Deejayen
Deejayen

Reputation: 23

kotlin rounding off in BigDecimal

import java.math.BigDecimal

BigDecimal(0.235).setScale(2, BigDecimal.ROUND_HALF_UP) // 0.23

BigDecimal("0.235").setScale(2, BigDecimal.ROUND_HALF_UP) // 0.24

In kotlin, when input 0.235 is given as double then the output is 0.23. when input 0.235 is given as string then the output is 0.24

Here is the definition of ROUND_HALF_UP given in the documentation:

Rounding mode where values are rounded towards the nearest neighbor. Ties are broken by rounding up.

Upvotes: 1

Views: 3672

Answers (2)

Adam Millerchip
Adam Millerchip

Reputation: 23091

From the BigDecimal docs:

  1. The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
  2. The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.

Upvotes: 2

Tim Biegeleisen
Tim Biegeleisen

Reputation: 520878

The issue here is that in the first case you are calling the BigDecimal constructor using a floating point (read: not exact) literal. Consider the following script (in Java):

BigDecimal blah = new BigDecimal(0.235d);
System.out.println(blah);

This prints 0.23499999999999998667732370449812151491641998291015625 in my demo tool. That is, you are not actually passing in literal 0.235, but rather a floating point approximation to it. It so happens, in this case, that the actual literal value is slightly less than 0.235, leading the round half up to result in 0.23 rather than 0.24.

Upvotes: 0

Related Questions