# Unisex 9 Asics White Multicolour pink Pink Adults' Impression T6f6n Gel 2030 0000001 Trainers Cross P6IIqrdnW

Not all Java developers need the precision that BigDecimal offers. However, those who do usually don't have to use BigDecimal for very long before running into the Shoes Asolo ml Grigio Grey Gunmetal Rise Hiking Women’s A177 Finder Pool High Gv trZ0wr with message "Non-terminating decimal expansion; no exact representable decimal result." Jaydeep provides an excellent overview of what this exception is, why it is thrown with some divide operations on BigDecimal instances, and how to avoid it. In this blog post, I only briefly look at the issue from a Java perspective before moving onto how Groovy handles it.

The following simple code snippet demonstrates how easy it is to encounter this ArithmeticException when dividing BigDecimal instances. I use the simplest rational number with non-terminating decimal representation that I can think of (1/3) for this example.

Main.java Demonstrating Arithmetic Exception on BigDecimal.divideWinter Shoes For Toe Novelty Boots CN34 Fall Boots Pu Round Booties EU35 Women'S Leatherette Buckle RTRY Party Fashion Comfort Boots US5 Chunky UK3 Heel Ankle amp;Amp; Fq6wH5X0x

package dustin.examples; import java.math.BigDecimal; import static java.lang.System.out; public class Main { public static void main(final String[] arguments) { final BigDecimal dividend = new BigDecimal("1"); final BigDecimal divisor = new BigDecimal("3"); out.println("1/3 = " + dividend.divide(divisor)); } }

When the above code is executed, the expected exception is encountered as shown in the next screen snapshot (and listed after that image in text).

Asics Cross T6f6n 0000001 2030 Trainers 9 Pink Unisex Impression pink Gel White Multicolour Adults'

The text version of the above screen snapshot is shown next.

Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. at java.math.BigDecimal.divide(BigDecimal.Multicolour 2030 Asics Impression T6f6n 9 0000001 Adults' Gel White Cross Trainers pink Pink Unisex java:1616) at dustin.pink 0000001 9 Asics Pink White T6f6n Cross Gel 2030 Unisex Trainers Multicolour Adults' Impression examples.Main.main(Main.java:13)

It is well-known among Groovy developers that Groovy automatically and implicitly often uses BigDecimal for any floating-point numbers. So, does Groovy run into this same problem? The next example is a short Groovy script that helps answer that question.

demoBigDecimalDivide.groovy

#!/usr/bin/env groovy def dividend = 1.0 def divisor = 3.0 def quotient = dividend / divisor println "1/3 = \${quotient}"

Although it's not the point of this particular post, it's difficult to not notice how succinct the Groovy code is. I don't show it here, but if I printed out the .getClass() results on the three defined numerals in this script, they'd all come back as java.math.BigDecimal. The next screen snapshot shows the results of running this Groovy script (along with printing of the three defined variables' class types) that is really the equivalent of the previous Java example.

Lace UK8 Stiletto Leatherette Round Knee For US10 Women'S 5 Over Up Novelty Pu 5 CN43 Fashion Fall Shoes Boots Heel Winter RTRY Toe Comfort EU42 Boots The Boots OHP4w

The Groovy script does not throw an exception! The next question would be where does it stop the repeating decimal representation and we can see from the above screen snapshot that it does so after providing ten "3" digits after the decimal point (0.3333333333).

There are often times when not using Groovy that it is advantageous to have a rounded representation of a quotient rather than an ArithmeticException when the quotient cannot be represented exactly. The following code listing demonstrates how overloaded versions of the BigDecimal.divide methods can be used to obtain a rounded answer.

Main.java Demonstrating Overloaded Versions of BigDecimal.divide

The output from running the above is shown next.

There are a few interesting observations that can be made from this output when compared to the code that generated the output.

It is easy to confirm that Groovy uses a scale of 10 in the case of dividing one or two by three to represent the non-terminating rational numbers that cannot be represented exactly. The revised Groovy script does this.

#!/usr/bin/env groovy def one = 1.0 def two = 2.0 def three = 3.0 def oneThird = one / three def twoThird = two / three println "1/3 = \${oneThird}" println "2/3 = \${twoThird}" println oneThird.dump() println twoThird.dump()

The output from running this script (shown in the next screen snapshot) proves that the scale is 10 and that the rounding mode is one that allows for 1/3 to end with a "3" and for 2/3 to end with a "7."

T6f6n Pink Cross Adults' Impression 2030 Trainers pink White Gel Unisex 9 Multicolour Asics 0000001

Groovy uses BigDecimal implicitly

, so it is generally desirable that it provides overloaded operators and implicit rounding and scaling. However, there may be cases where one needs a different level of scaling. In such cases, it is possible to call the divide method explicitly rather than counting on the overloaded operator and to provide the scaling. This is demonstrated in the next Groovy code listing.

#!/usr/bin/env groovy import static java.math.RoundingMode.HALF_UP def one = 1.0 def two = 2.0 def three = 3.0 def oneThird = one.divide(three, 15, HALF_UP) def twoThird = two.divide(three, 20, HALF_UP) println "1/3 = \${oneThird}" println "2/3 = \${twoThird}" println oneThird.dump() println twoThird.dump()

The output from the above is shown in the next screen snapshot, which includes the output from the previous run as well for easy comparison.

There might be a situation in which the developer actually wants an

ArithmeticException

to be thrown to indicate that an exact representation is not available for a division call. This can be enforced in Groovy by making an explicit divide call (via method name rather than overloaded

/

operator) and providing a rounding mode of

UNNECESSARY

as shown in the next code listing (assumes local variables one and three as defined above).

def exception = one.divide(three, White Impression pink 9 0000001 Asics 2030 Trainers Multicolour Cross T6f6n Adults' Unisex Gel Pink 10, RoundingMode.UNNECESSARY)

When executed, the

ArithmeticException

is encountered with a messages simply stating "Rounding necessary." This is shown in the next screen snapshot.

Conclusion

Java's

BigDecimal

is handy when one desires better precision than

double

or

float

can support. However, it must throw an

ArithmeticException

when a quotient result of one of the overloaded

BigDecimal.divide

calls cannot be represented exactly so that client code does not presume that the quotient provided is an exactly representation. Java allows the caller to explicitly specify a scale and type of rounding to avoid this exception. This mechanism ensures that the caller recognizes that rounding may occur to avoid an exception. The caller gets to specify the rules of that rounding and of the scale.

Groovy makes heavy implicit use of BigDecimals and makes many assumptions about how these are used. In the situations where Groovy's rules or conventions for BigDecimal are not desirable, the Groovy developer can use traditional Java syntax and specific and explicit method calls to get the desired behavior. For most of my uses, the Groovy default conventions for BigDecimal are sufficient. However, I believe it is useful to be aware of its implicit assumptions for situations in which they are not so desirable.

Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)

Related: