Wiki Markup |
---|
The Java language provides two primitive types, {{float}} and {{double}}, which "are conceptually associated with the single-precision 32-bit and double-precision 64-bit format IEEE 754 values and operations as specified in IEEE Standard for Binary Floating-Point Arithmetic, ANSI/IEEE Standard 754-1985 (IEEE, New York)" (\[[JLS 2005|AA.Bibliography#JLS 05]\]. [Section 4.2.3|http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3] "Floating-Point Types, Formats, and Values"). Each of the floating point types has a fixed, limited number of mantissa bits. Consequently, it is impossible to precisely represent any irrational number (_e.g._ pi). Further, because these types use a binary mantissa, they cannot precisely represent many finite decimal numbers, such as 1/10, because these numbers have repeating binary representations. |
Wiki Markup |
---|
Avoid using the primitive floating point types when precise computation is necessary, and especially when performing currency calculations. Rather, consider alternative representations that are be able to completely represent the necessary values. Whatever representation you choose, carefully and methodically estimate the maximum cumulative error of the computations to ensure that the resulting error is within tolerances. Consider using numerical analysis to properly understand the problem. See \[[Goldberg 1991|AA. Bibliography#Goldberg 91]\] for an introduction to these issues |
Computers can represent only a finite number of digits. Consequently, it is impossible to precisely represent repeating binary sequences of floating point numbers. This includes many finite decimal numbers, such as 1/10 which have repeating binary representations.
When precise computation is necessary, and especially when doing currency calculations, consider alternative representations that may be able to completely represent values rather than employing the floating point representations float
and double
. |
Noncompliant Code Example
...
Unfortunately, because of the imprecision of 1/10 cannot be represented precisely in any binary floating point arithmeticformat, this program prints:
A dollar less 7 dimes is $0.29999999999999993
...
Guideline | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
FLP00-J | low | probable | high | P2 | L3 |
Automated Detection
TODOAutomated detection of floating point arithmetic is straight-forward; determining which code suffers from insufficient precision is not feasible in the general case. Heuristic checks, such as flagging floating point literals that cannot be represented precisely, may be useful.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this guideline on the CERT website.
...
This guideline appears in the C++ Secure Coding Standard as FLP02-CPP. Avoid using floating point numbers when precise computation is needed.
Bibliography
Wiki Markup |
---|
\[[JLS 2005|AA. Bibliography#JLS 05]\] [Section 4.2.3, Floating-Point Types, Formats, and Values|http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3] \[[Bloch 2008|AA. Bibliography#Bloch 08]\] Item 48: Avoid {{float}} and {{double}} if exact answers are required \[[Bloch 2005|AA. Bibliography#Bloch 05]\] Puzzle 2: Time for a Change \[[Goldberg 1991|AA. Bibliography#Goldberg 91]\] \[[JLS 2005|AA. Bibliography#JLS 05]\] [Section 4.2.3, Floating-Point Types, Formats, and Values|http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3] |
...
07. Floating Point (FLP) 07. Floating Point (FLP) FLP01-J. Take care in rearranging floating point expressions