Versions Compared

Key

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

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
bgColor#ffcccc
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
bgColor#ccccff
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.

...