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.
According to the Java Language Specification \[[JLS 2005|AA. Bibliography#JLS 05]\], section Specification Section 4.2.2 " Integer Operations",Wiki Markup
If an integer operator other than a shift operator has at least one operand of type
long, then the operation is carried out using 64-bit precision, and the result of the numerical operator is of typelong. If the other operand is notlong, it is first widened (§5.1.5) to typelongby numeric promotion (§5.6). Otherwise, the operation is carried out using 32-bit precision, and the result of the numerical operator is of typeint. If either operand is not anint, it is first widened to typeintby numeric promotion.
The Java Language Specification \[[JLS 2005|AA. Bibliography#JLS 05]\] section JLS Section 5.6 " Numeric Promotions" describes numeric promotion as the following: Wiki Markup
- If any of the operands is of a reference type, unboxing conversion is performed. Then:
- If either operand is of type double, the other is converted to double.
- Otherwise, if either operand is of type float, the other is converted to float.
- Otherwise, if either operand is of type long, the other is converted to long.
- Otherwise, both operands are converted to type int.
Widening conversions resulting from integer promotions preserve the overall magnitude of the number. However, promotions in which the operands are converted from a numeric type such as an int to a float or from a long to a double, are particularly pernicious. (See may cause unexpected loss of precision (see guideline INT03-J. Do not cast numeric types to wider floating-point types without range checking for more details.) These implicit casts can lead to loss of precision.
These conversions can happen with the following operators: multiplicative operators (%, *, /), additive operators (+, -), comparison operators (<, >, <=, >=), equality operators (==, !=) and the integer bitwise operators (&, |, ^).
...
| Code Block | ||
|---|---|---|
| ||
class Test{
public static void main(String[] args){
int big = 1999999999;
double one = 1.0d; // double instead of float
System.out.println(big*one);
}
}
|
This produces the required expected output of 1.999999999E9. This is the value that is obtained when an int is assigned (implicitly cast) to a double.
...
| Wiki Markup |
|---|
This noncompliant code example shows integer promotion resulting from the use of the bit-wise OR operator. The byte array element is sign extended to 32 bits before it is used as an operand. If it originally contained the value {{0xff}}, now it would contain {{0xffffffff}} \[[Findbugs 2008|AA. Bibliography#Findbugs 08]\]. |
...
Compliant Solution
This compliant solution does not avoid continues to use integer promotion, but works around it by masking masks off the upper 24 bits of the byte array element to achieve the intended result.
| Code Block | ||
|---|---|---|
| ||
int result = 0; for(int i = 0; i < 4; i++) result = ((result << 8) | (b[i] & 0xff)); |
...
Guideline | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
EXP05-J | low | probable | medium | P4 | L3 |
Automated Detection
TODOAutomated detection of numeric promotion is straightforward. Determining which promotions may be problematic is infeasible in the general case. A heuristic approach may provide acceptable results.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this guideline on the CERT website.
...
| Wiki Markup |
|---|
\[[JLS 2005|AA. Bibliography#JLS 05]\] [Section 4.2.2||http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.2], "Integer Operations" and [Section 5.6|http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.6], "Numeric Promotions" \[[Findbugs 2008|AA. Bibliography#Findbugs 08]\] "BIT: Bitwise OR of signed byte value" |
...