Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Java uses the IEEE 754 standard for floating-point representation. In this representation, floats are encoded using 1 sign bit, 8 exponent bits, and 23 mantissa bits. Doubles are encoded and used exactly the same way, except they use 1 sign bit, 11 exponent bits, and 52 mantissa bits. These bits encode the values of s, the sign; M, the significand; and E, the exponent. Floating point numbers are then calculated as (-1)s * M * 2 E.

Ordinarily, all of the mantissa bits are used to express significant figures, in addition to a leading 1, which is implied and, therefore, left out. Floats, consequently, have 24 significant bits of precision; doubles have 53 significant bits of precision. Such numbers are called normalized numbers. All-floating point numbers are limited in this sense that because they have fixed precision.

When the value to be represented is too small to encode normally, it is encoded in denormalized form, indicated by an exponent value of Float.MIN_EXPONENT - 1 or Double.MIN_EXPONENT - 1. Denormalized floating-point numbers have an assumed 0 in the ones place , and have a zero or more leading zeros in the represented portion of their mantissa. These leading zero bits no longer function as significant bits of precision; consequently, the total precision of denormalized floating-point numbers is less than that of normalized floating-point numbers. Note that even use of using normalized numbers where precision is required can pose a risk. See recommendation guideline "NUM07-J. Avoid using floating-point numbers when precise computation is required. " for more information.

Use of Using denormalized numbers can severely impair the precision of floating-point calculations; consequently as a result, denormalized numbers must not be used.

...

The following code tests whether a float value is denormalized in strictfp mode, or for platforms that lack extended range support. Testing for denormalized numbers in the presence of extended range support is platform dependent; see guideline "NUM09-J. Use the strictfp modifier for floating point calculation consistency across platforms" for additional information.

...

Denormalized numbers can also be troublesome because their printed representation is unusual. Floats and normalized doubles, when formatted with the %a specifier, begin with a leading nonzero digit. Denormalized doubles can begin with a leading zero to the left of the decimal point in the mantissa.

The following program produces the following this output:

Code Block
class FloatingPointFormats {
    public static void main(String[] args) {
        float x = 0x1p-125f;
        double y = 0x1p-1020;
        System.out.format("normalized float with %%e    : %e\n", x);
        System.out.format("normalized float with %%a    : %a\n", x);
        x = 0x1p-140f;
        System.out.format("denormalized float with %%e  : %e\n", x);
        System.out.format("denormalized float with %%a  : %a\n", x);
        System.out.format("normalized double with %%e   : %e\n", y);
        System.out.format("normalized double with %%a   : %a\n", y);
        y = 0x1p-1050;
        System.out.format("denormalized double with %%e : %e\n", y);
        System.out.format("denormalized double with %%a : %a\n", y);
    }
}

...

This code attempts to reduce a floating-point number to a denormalized value and then restore the value.

...

Do not use code that could use denormalized numbers. When calculations using float produce denormalized numbers, use of double may can provide sufficient precision.

...

NUM08-EX1: Denormalized numbers are acceptable when competent numerical analysis demonstrates that the computed values will meet all accuracy and behavioral requirements that are appropriate to the application. Note that "competent numerical analysis" generally requires a specialized professional numerical analyst; lesser levels of rigor fail to qualify for this exception.

Risk Assessment

Floating-point numbers are an approximation; denormalized floating-point numbers are a less precise approximation. Use of denormalized numbers can cause unexpected loss of precision, and consequently can lead possibly leading to incorrect or unexpected results. Although the severity stated below for violations of this guideline is " low", applications that require accurate results should consider the severity of violations this violation to be high.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

NUM08-J

low

probable

high

P2

L3

...

CERT C Secure Coding Standard: "FLP05-C. Don't use denormalized numbers"

Bibliography

<ac:structured-macro ac:name="unmigrated-wiki-markup

...

" ac:schema-version="1" ac:macro-id="235d5711-a486-431a-ad44-5019c28325ee"><ac:plain-text-body><![CDATA[

[[IEEE

...

754

...

AA.

...

Bibliography#IEEE

...

754

...

2006]

...

]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="55d09ea0-b5cf-41cb-b41d-0691dd6caab0"><ac:plain-text-body><![CDATA[

[[Bryant 2003

AA. Bibliography#Bryant 03]]

Computer Systems: A Programmer's Perspective. Section 2.4 Floating Point

]]></ac:plain-text-body></ac:structured-macro>

...

NUM07-J. Avoid using floating-point numbers when precise computation is required      03. Numeric Types and Operations (NUM)      NUM09-J. Use the strictfp modifier for floating point calculation consistency across platforms