...
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 | ||
|---|---|---|
| ||
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 | ||
|---|---|---|
| ||
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 | ||
|---|---|---|
| ||
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.
...