
Using integer arithmetic to calculate a value for assignment to a floating-point variable may lead to loss of information. This can be avoided by converting one of the integers in the expression to a floating type.
When converting integers to floating-point values, it is important to be aware that there may be a loss of precision (see INT33-J. Be careful while casting numeric types to wider floating-point types).
Noncompliant Code Example
In this noncompliant code example the division and multiplication operations take place on integers and then get converted to floating point. This causes floating-point variables d
, e
, and f
to not be initialized correctly because the operations take place before the values are converted to floating-point values. The results are truncated to the nearest integer or may overflow.
short a = 533; int b = 6789; long c = 4664382371590123456L; float d = a / 7; // d is 76.0 double e = b / 30; // e is 226.0 double f = c * 2; // f is -9.1179793305293046E18 due to overflow
Compliant Solution (Floating Point Literal)
In this compliant solution, the decimal error in initialization is eliminated by ensuring that at least one of the operands to the division operation is floating point.
short a = 533; int b = 6789; long c = 4664382371590123456L; float d = a / 7.0f; // d is 76.14286 double e = b / 30.; // e is 226.3 double f = (double)c * 2; // f is 9.328764743180247E18
Compliant Solution 2
In this compliant solution, the decimal error in initialization is eliminated by first storing the integer in the floating-point variable and then performing the arithmetic operation. This ensures that at least one of the operands is a floating-point number, and consequently the operation is performed on floating point numbers.
short a = 533; int b = 6789; long c = 4664382371590123456L; float d = a; double e = b; double f = c; d /= 7; // d is 76.14286 e /= 30; // e is 226.3 f *= 2; // f is 9.328764743180247E18
Exceptions
FLP31-EX1: If it is the programmer's intention to have the operation take place as integers before the conversion (obviating the need for a call to floor()
, for example) it should be clearly documented to help future maintainers understand that this behavior is intentional.
Risk Assessment
Improper conversions between integers and floating point values may yield unexpected results, especially loss of precision. Additionally, these unexpected results may actually involve overflow, or undefined behavior.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
FLP31-J |
low |
probable |
low |
P6 |
L2 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
This rule appears in the C Secure Coding Standard as FLP33-C. Convert integers to floating point for floating point operations.
This rule appears in the C++ Secure Coding Standard as FLP33-CPP. Convert integers to floating point for floating point operations.
References
[[JLS 05]] Section 5.1.2, Widening Primitive Conversion
FLP30-J. Do not use floating point variables as loop counters 06. Floating Point (FLP) 07. Object Orientation (OBJ)