Synopsis: | Avoid creating BigDecimal with a decimal (float/double) literal. Use a String literal |
Language: | Java |
Severity Level: | 1 |
Category: | Basic |
Description: |
It is generally recommended that the valueOf() should be used in preference to BigDecimal constructor with float/double parameter. The value returned is equal to that resulting from using the BigDecimal constructor with String parameter. Note: valueOf() will use the canonical String representation of thedoublevalue passed in to instantiate theBigDecimal object. In other words: The value of theBigDecimalobject will be what you see when you doSystem.out.println(d). import java.math.BigDecimal; public class Test { public static void main(String[] args) { // this would trigger the rule BigDecimal bd=new BigDecimal(1.123); // this wouldn't trigger the rule BigDecimal bd=new BigDecimal("1.123"); // this wouldn't trigger the rule BigDecimal bd=new BigDecimal(12); } } Justification: One might assume that "new BigDecimal(.1)" is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances notwithstanding. The (String) constructor, on the other hand, is perfectly predictable: 'new BigDecimal(".1")' is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one. |