Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scale() of Divide method in BigDecimal

new BigDecimal("37146555.53880000").divide(new BigDecimal("1000000")).scale()

This returns 10. But according to the API, the divide method:

Returns a BigDecimal whose value is (this / divisor), and whose preferred scale is (this.scale() - divisor.scale());

So in this case, 37146555.53880000's scale is 8, and 1000000's scale is 0. So the result should have a scale of 8, not 10.

What am I missing here?

Thanks

like image 343
Saobi Avatar asked Jul 21 '10 20:07

Saobi


People also ask

What is scale in BigDecimal divide?

A BigDecimal consists of an arbitrary precision integer unscaled value and a 32-bit integer scale. If zero or positive, the scale is the number of digits to the right of the decimal point. If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale.

How do you divide a big decimal?

divide(BigDecimal divisor)scale() – divisor. scale()). Parameters: This method accepts a parameter divisor by which this BigDecimal is to be divided for obtaining quotient. Return value: This method returns a BigDecimal which holds the result (this / divisor).

What is RoundingMode in BigDecimal Java?

public enum RoundingMode extends Enum<RoundingMode> Specifies a rounding behavior for numerical operations capable of discarding precision. Each rounding mode indicates how the least significant returned digit of a rounded result is to be calculated.

How many digits can BigDecimal hold in Java?

By default, BigDecimal numbers have “unlimited” precision. In fact, the maximum unscaled value is equal to 2^Integer.


1 Answers

The actual result is 37.1465555388 whose scale must be 10 for it to be exact.

What the JavaDoc says is that the preferred scale is the difference meaning that if the result didn't actually need to be 10, then it would try to make it 8. For example if you would have divided by 2, whose scale is also 0, the result would have been 18573277.76940000 (scale 8).

EDIT: small adition - you can force the division to a certain scale by using the overloaded divide methods:

  • divide(BigDecimal, RoundingMode) that will give a BigDecimal with scale of this and value rounded using the specified rounding method if the result would actually need more decimals to be exact.

  • divide(BigDecimal, scale, RoundingMode) that will give a BigDecimal with specified scale, and value rounded by specified method if needed.

This might be useful if your dividing by a number you know can cause repeating decimals, like 3 (1/3 = 0.333333...) since, if that happens, the simple divide will throw an exception. Bounding it to a maximum number of decimals will help you avoid the exception but will make your computations less precise.

like image 145
Andrei Fierbinteanu Avatar answered Oct 05 '22 03:10

Andrei Fierbinteanu