Canonical representation of BigDecimal

What is the easiest way to reduce Java BigDecimal containing an arbitrary value in canonical form, so that two BigDecimal representing the same number compare equal using equals() method?

I parse my numbers from arbitrary strings using the following code:

 BigDecimal x = new BigDecimal(string1, MathContext.DECIMAL64); BigDecimal y = new BigDecimal(string2, MathContext.DECIMAL64); 

Since ( string1 , string2 ) are arbitrary, they can be, for example, ( "1" , "1.0000" ) or ( "-32.5" , "1981" ) ...

I am looking for the simplest (shortest / cleanest code) implementation of the canonicalize method, for which the above statement

 assert x.compareTo(y) != 0 || (canonicalize(x).equals(canonicalize(y)) && x.compareTo(canonicalize(x)) == 0 && y.compareTo(canonicalize(y)) == 0); 

will succeed...:

 public static BigDecimal canonicalize(BigDecimal b) { // TODO: } 
+6
source share
2 answers

If you want to know if two BigDecimal equal regardless of scale, just use .compareTo()

 public static boolean bigDecimalEquals(BigDecimal b1, BigDecimal b2) { return b1.compareTo(b1) == 0; } 

He recommends this at Javadoc

Two BigDecimal objects that are equal in cost but have a different scale (for example, 2.0 and 2.00) are considered equal by this method. This method is provided in preference to individual methods for each of the six Boolean comparison operators (<, ==,>,> = ,! =, <=).


If you really want to convert BigDecimal for .equals() work, just use the setScale method.

+2
source

Use stripTrailingZeros() . This returns the equivalent of BigDecimal with minimization of scale and is the easiest way to get a canonical representation. This is better than setScale() because it avoids any rounding issues.

0
source

Source: https://habr.com/ru/post/976688/


All Articles