I want to round a Java BigDecimal
to a certain number of significant digits (NOT decimal places), e.g. to 4 digits:
12.3456 => 12.35 123.456 => 123.5 123456 => 123500
etc. The basic problem is how to find the order of magnitude of the BigDecimal
, so I can then decide how many place to use after the decimal point.
All I can think of is some horrible loop, dividing by 10 until the result is <1, I am hoping there is a better way.
BTW, the number might be very big (or very small) so I can't convert it to double to use Log on it.
Why not just use round(MathContext)
?
BigDecimal value = BigDecimal.valueOf(123456);
BigDecimal wantedValue = value.round(new MathContext(4, RoundingMode.HALF_UP));
The easierst solution is:
int newScale = 4-bd.precision()+bd.scale();
BigDecimal bd2 = bd1.setScale(newScale, RoundingMode.HALF_UP);
No String conversion is necessary, it is based purely on BigDecimal
arithmetic and therefore as efficient as possible, you can choose the RoundingMode
and it is small. If the output should be a String
, simply append .toPlainString()
.
You can use the following lines:
int digitsRemain = 4;
BigDecimal bd = new BigDecimal("12.3456");
int power = bd.precision() - digitsRemain;
BigDecimal unit = bd.ulp().scaleByPowerOfTen(power);
BigDecimal result = bd.divideToIntegralValue(unit).multiply(unit);
Note: this solution always rounds down to the last digit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With