Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

String representations of floating point values may lead to incorrect conclusions about the precision of the values. For example, consider converting a value of type float to the type double, a widening primitive conversion. Refer to the guideline INT03-J. Avoid casting primitive integer types to floating-point types without range checks for more details about such conversions. If When the value of the float variable must be represented exactly using the double type, an explicit assignment is more appropriate than first converting the floating point value to a String and then to a double.

Noncompliant Code Example

This noncompliant code example converts a value of type float to a value of type double. The float variable contains the equivalent of 1/3 (0.3333333432674408). However, the default string representation can mislead a programmer into thinking that the correct value is 0.33333334. Consequently, the double variable may acquire an imprecise value. The imprecise value arises from the default precision used for converting floating point numbers to a string.

Code Block
bgColor#FFCCCC

double d;
float f = 1/3f; // Contains the value 0.33333334
d = Double.valueOf(String.valueOf(f)); // Now contains the value 0.33333334

Compliant Solution

This compliant solution assigns the value of type float to the double variable directly.

...

bgColor#ccccff

...

double

...

.

...

Noncompliant Code Example

This noncompliant code example obtains the result of 1/1000.0 and represents it as a String. However, even though the resulting value is precise, an extra zero digit is appended at the end. Any operations on the string, such as comparisons, may yield incorrect results.

Code Block
bgColor#FFCCCC
int i = 1;
String s = Double.valueOf (i / 1000.0).toString(); // s contains 0.0010
if(s.equals("0.001")) { // Fails
  // Do something
}

Noncompliant Code Example

This noncompliant code example attempts to use a regular expression to eliminate the trailing zeros. However, even though this works for 1/1000.0, for 1/10000.0, it produces the string 1.0E-4 because of which the regular expression fails to work as expected. Subsequent comparison operations can still fail.

Code Block
bgColor#FFCCCC
int i = 1;
String s = Double.valueOf (i / 10000.0).toString(); // s contains 0.0010
s = s.replaceFirst("[.0]*$", "");
// ...

Compliant Solution

This compliant solution uses the BigDecimal class and strips the trailing zeros so that future operations do not fail.

...