Note | ||
---|---|---|
| ||
This rule may be deprecated and replaced by a similar guideline. 06/28/2014 -- Version 1.0 |
The Java language provides two primitive floating-point types, float
and double
, which are associated with the single-precision 32-bit and double-precision 64-bit format values and operations specified by IEEE 754 [IEEE 754]. Each of the floating-point types has a fixed, limited number of mantissa bits. Consequently, it is impossible to precisely represent any irrational number (for example, pi). Further, because these types use a binary mantissa, they cannot precisely represent many finite decimal numbers, such as 0.1, because these numbers have repeating binary representations.
...
This noncompliant code example performs some basic currency calculations.:
Code Block | ||
---|---|---|
| ||
double dollar = 1.00; double dime = 0.10; int number = 7; System.out.println( "A dollar less " + number + " dimes is $" + (dollar - number * dime) ); |
Because the value 0.10 lacks an exact representation in either Java floating-point type (or any floating-point format that uses a binary mantissa), on most platforms, this program prints the following:
Code Block |
---|
A dollar less 7 dimes is $0.29999999999999993 |
...
This compliant solution uses an integer type (such as int
) and works with cents rather than dollars.:
Code Block | ||
---|---|---|
| ||
int dollar = 100; int dime = 10; int number = 7; System.out.println( "A dollar less " + number + " dimes is $0." + (dollar - number * dime) ); |
This code correctly outputs the following:
Code Block |
---|
A dollar less 7 dimes is $0.30 |
...
Code Block | ||
---|---|---|
| ||
import java.math.BigDecimal; BigDecimal dollar = new BigDecimal("1.0"); BigDecimal dime = new BigDecimal("0.1"); int number = 7; System.out.println ("A dollar less " + number + " dimes is $" + (dollar.subtract(new BigDecimal(number).multiply(dime) )) ); |
This code outputs the following:
Code Block |
---|
A dollar less 7 dimes is $0.3 |
...
Using floating-point representations when precise computation is required can result in a loss of precision and incorrect values.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
NUM04-J |
Low |
Probable |
High | P2 | L3 |
Automated Detection
Automated detection of floating-point arithmetic is straight forwardstraightforward. However, 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, could be useful.
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Parasoft Jtest |
| CERT.NUM04.UBD | Do not use "float" and "double" if exact answers are required |
Related Guidelines
FLP02-C. Avoid using floating-point numbers when precise computation is needed | |
VOID FLP02-CPP. Avoid using floating point numbers when precise computation is needed | |
Floating-Point Arithmetic [PLF] |
Android Implementation Details
The use of floating-point on Android is not recommended for performance reasons on Android.
Bibliography
Item 48 |
, "Avoid |
If Exact Answers Are Required" | |
Puzzle 2 |
, "Time for a |
Change" |
[IEEE 754] |
[JLS |
2015] |
[Seacord 2015] |
...
...