When using binary operators with mixed operand sizes, be aware that some of the narrower operands may be promoted to a wider type, to match the type of the other operand. For example in the expression 'a' == 42, the field 'a' which is shorter than an int will be promoted to an int before the comparison is carried out.
...
| Code Block |
|---|
int a = some_value; char b = some_character; if((a + b) ==> 01.0f1f) { //do something } |
Here, b is first converted to int so that the + operator can be applied to operands of the same type. The result of (a+b) is then converted to a float, and the comparison operator is finally applied.
Noncompliant Code Example
Here is an example of what could happenIn this noncompliant code example, the statement big * one carries out a binary operation. As big is an int and one is of type float, big is promoted to a float. This implicit case results in loss of precision.
| Code Block | ||
|---|---|---|
| ||
class Test{
public static void main(String[] args){
int big = 1999999999;
double big_float = big;
float one = 1.0f;
System.out.println(big*one); // binary operation, loses precision due to implicit cast
System.out.println(big_float); // double is a wider type, preserves precision
}
}
|
The output is:
| Code Block |
|---|
2.0E9 |
...
// loss of precision 1.999999999E9 |
while Whereas, the expected output is: 2.0E9
2.0E9.
big is first converted to a float, and loses some precision, which explains the 2.0E9. However, big_float doesn't lose any precision since it's a wider type than float, this is why the two output are different.
| Code Block |
|---|
1.999999999E9
1.999999999E9
|
Compliant solution
In that particular this case, it would be sufficient to use a double should be used instead of a float : for a safe widening primitive conversion caused by integer promotion.
| Code Block | ||
|---|---|---|
| ||
class Test{
public static void main(String[] args){
int big = 1999999999;
double big_float = big;
double one = 1.0d; // double instead of float
System.out.println(big*one);
System.out.println(big_float);
}
}
|
the The output is what is as expected :
| Code Block |
|---|
1.999999999E9 |
...
1.999999999E9 |
...
|
Risk assessment
Failing to consider integer promotions while dealing with floating point and integer operands together, can result in loss of precision.
...