You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Narrower primitive types can be cast to wider types without any effect on the magnitude of numeric values. However, when the expressions are not strictfp, conversions from float to double may lose information about the overall magnitude of the converted value. JLS 5.1.2

Conversion from int or long to float, or long to double can lead to loss of precision (loss of least significant bits). No run-time exception occurs despite the loss.

Conversion rules:

From

To

Description

int or long

integral type T

Sign extend corresponding 2's complement form

char

integral type T

Zero extend representation of char value

Non-Compliant Code Example

In this non-compliant example, an int is converted to float. Since a floating point number cannot be precise to 9 digits, the result of subtracting the original from this value is non-zero.

class wideSample {
  public static void main(String[] args) {
    int big = 1234567890;
    float approx = big;
    System.out.println(big - (int)approx);  //ideally this should be zero but it prints -46
  }
}

Compliant Solution

The significand part of a floating point number can hold at most 23 bit values. Anything above this threshold is discarded due to precision loss, as is demonstrated in this compliant solution.

class wideSample {
  public static void main(String[] args) {
    int big = 1234567890;
                
    float approx = big;
    if(Integer.highestOneBit(big) <= Math.pow(2, 23)) { //the significand can store at most 23 bits
      System.out.println(big - (int)approx);  //always prints zero now
    }
    else {
      //handle error   //precision error
    }
  }
}

References

JLS 5.1.2 Widening Primitive Conversion

  • No labels