You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 60 Next »

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, and vice versa, it is important to carry out proper range checks to avoid undefined behavior. (See rule FLP34-C. Ensure that floating point conversions are within range of the new type.)

Noncompliant Code Example

In this noncompliant code example, the division and multiplication operations take place on integers and are then 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 = 466438237;

float d = a / 7; /* d is 76.0 */
double e = b / 30; /* e is 226.0 */
double f = c * 789; /*  f may be negative 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 = 466438237;

float d = a / 7.0f; /* d is 76.14286 */
double e = b / 30.; /* e is 226.3 */
double f = (double)c * 789; /* f is 368019768993.0 */

Compliant Solution (Conversion)

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 that the subsequent arithmetic operation is performed on floating point operands.

short a = 533;
int b = 6789;
long c = 466438237;

float d = a;
double e = b;
double f = c;

d /= 7; /* d is 76.14286 */
e /= 30; /* e is 226.3 */
f *= 789; /* f is 368019768993.0 */

Exceptions

FLP33-EX1: It may be desirable to have the operation take place as integers before the conversion (obviating the need for a call to trunc(), for example). If this is the programmer's intention, 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

FLP33-C

low

probable

low

P6

L2

Automated Detection

Tool

Version

Checker

Description

9.7.1

 

 

Splint

3.1.1

 

 

Compass/ROSE

 

 

can detect violations of this rule. Any assignment operation where the type of the assigned-to value is float or double, but all the expressions to the right of the assignment are integral is a violation of this rule

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

CERT C++ Secure Coding Standard: FLP33-CPP. Convert integers to floating point for floating point operations

The CERT Oracle Secure Coding Standard for Java: NUM13-J. Convert integers to floating point for floating-point operations

ISO/IEC 9899:1999 Section 5.2.4.2.2, "Characteristics of floating types <float.h>"

MITRE CWE: CWE-681, "Incorrect Conversion between Numeric Types

MITRE CWE: CWE-682, "Incorrect Calculation"

Bibliography

[Hatton 1995] Section 2.7.3, "Floating-point misbehavior"


      05. Floating Point (FLP)      FLP34-C. Ensure that floating point conversions are within range of the new type

  • No labels