...
Java provides 22 possible narrowing primitive conversions. According to The Java Language Languagee Specification (JLS), §5.1.3, "Narrowing Primitive Conversions" [JLS 20052015]:
short
tobyte
orchar
char
tobyte
orshort
int
tobyte
,short
, orchar
long
tobyte
,short
,char
, orint
float
tobyte
,short
,char
,int
, orlong
double
tobyte
,short
,char
,int
,long
, orfloat
...
Integer type ranges are defined by the JLS, §4.2.1, "Integral Types and Values" [JLS 20052015], and are also described in NUM00-J. Detect or prevent integer overflow.
The following table presents the rules for narrowing primitive conversions of integer types. In the table, for an integer type T
, n
represents the number of bits used to represent the resulting type T
(precision).
From | To | Description | Possible Resulting Errors |
---|---|---|---|
Signed integer | Integral type | Keeps only | Lost or misinterpreted data |
| Integral type | Keeps only | Magnitude error; negative number even though |
When integers are cast to narrower data types, the magnitude of the numeric value and the corresponding sign can be affected. Consequently, data can be lost or misinterpreted.
...
See the JLS, §5.1.3, "Narrowing Primitive Conversions," [JLS 2005], for more information.
Other Conversions
...
Note that conversions from float
to double
or from double
to float
can also lose information about the overall magnitude of the converted value (see rule NUM53-J. Use the strictfp modifier for floating-point calculation consistency across platforms for additional information).
...
The minimum and maximum float
values are converted to minimum 0 and maximum int
values (0x80000000
and 0x7fffffff
respectively). The resulting short
values are 0 and the lower 16 bits of these values this value (0x0000
and 0xffff
). The resulting final values (0 and −1) might be unexpected.
...
This compliant solution range-checks both the i
and j
variables before converting to the resulting integer type. Because both values are the maximum value is out of the valid range for a short
, this code will always throw an ArithmeticException
.
...
Casting a numeric value to a narrower type can result in information loss related to the sign and magnitude of the numeric value. As a result, data can be misrepresented or interpreted incorrectly.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
NUM12-J | Low | Unlikely | Medium | P2 | L3 |
Automated Detection
Automated detection of narrowing conversions on integral types is straightforward. Determining whether such conversions correctly reflect the intent of the programmer is infeasible in the general case. Heuristic warnings could be useful.
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
CodeSonar |
| JAVA.MATH.APPROX.E | Approximate e Constant (Java) | ||||||
Parasoft Jtest |
| CERT.NUM12.CLP | Do not cast primitive data types to lower precision |
Related Guidelines
INT31-C. Ensure that integer conversions do not result in lost or misinterpreted data | |
Numeric Conversion Errors [FLC] | |
CWE-681, Incorrect Conversion between Numeric Types |
Bibliography
[JLS 2005] | §4.2.1, "Integral Types and Values" |
[Seacord 2015] |
...
...