Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: not quite done, but closer

...

In this noncompliant code example, a value of type int is converted to the type float because of numeric promotions (see NUM10-J. Be aware of numeric promotion behavior) float is subtracted from a value of type int, and the result returned as a value of type int. Numbers of type float have 23 mantissa bits, a sign bit, and an 8 bit exponent. The exponent allows type float to represent a larger range than that of type int. Nevertheless, integers whose representation requires more than 23 bits can only be represented approximately by a float. Consequently, the result of subtracting the original from this value is -46, not zero.

Code Block
bgColor#FFcccc
class WideSample {
  public static floatint addFloatToIntsubFloatFromInt(int op1, float op2) {
    return op1 +- (int)op2;
  }

  public static void main(String[] args) {
    floatint result = addFloatToIntsubFloatFromInt(1234567890, 1234567890);
    // This prints -46, and not 0 as may be expected
    System.out.println(result);  
  }

}

Compliant Solution (

...

ArithmeticException)

This compliant solution replaces the float type double. Numbers of type double have 52 mantissa bits, a sign bit, and an 11 bit exponent. Consequently, integer values of type int and narrower can be converted to double without a loss of precision.

Code Block
bgColor#ccccff
class WideSample {
  public static voidint mainsubFloatFromInt(String[] args) {
    int big = 1234567890;
                  int op1, float op2) throws ArithmeticException {

    // The significand can store at most 23 bits
    if ((big > 0x007fffff) || (big < -0x800000)) { 
      throw new ArithmeticException("Insufficient precision");	
    }

    floatreturn approxop1 = big;
    System.out.println(big - (int)approx);  // Prints zero when no precision is lost- (int)op2;
  }

  public static void main(String[] args) {
    int result = subFloatFromInt(1234567890, 1234567890);
    System.out.println(result);  
  }
}

In this example, the subFloatFromInt() method throws java.lang.ArithmeticException.

Compliant Solution (

...

wider type)

This compliant solution replaces the float type double. Numbers of type float The most significant bit of a float or double is its sign bit. The mantissa occupies the 23 least significant bits of a float and the 52 least significant bits of a double. The exponent, 8 bits in a float and 11 bits in a double, sits between the sign and mantissa. . The exponent allows type float to represent a larger range than that of type int. Nevertheless, integers whose representation requires more than 23 bits can only be represented approximately by a float double have 52 mantissa bits, a sign bit, and an 11 bit exponent. Consequently, integer values of type int and narrower can be converted to double without a loss of precision.

Code Block
bgColor#ccccff
class WideSample {
  public static voidint main(String[] argssubDoubleFromInt(int op1, double op2) {
    intreturn bigop1 = 1234567890- (int)op2;
                  
    // The significand can store at most 23 bits}

  public static ifvoid main((big > 0x007fffff) || (big < -0x800000)String[] args) { 
    int result throw= new ArithmeticException("Insufficient precision"subDoubleFromInt(1234567890, 1234567890);	
    }

// Works   float approx = big;as expected
    System.out.println(big - (int)approx);  // Prints zero when no precision is lostresult);  
  }

}

Risk Assessment

Casting integer values to floating-point types whose mantissa has fewer bits than the original integer value will lose precision.

...