
In
computer science
Computer science is the study of computation, information, and automation. Computer science spans Theoretical computer science, theoretical disciplines (such as algorithms, theory of computation, and information theory) to Applied science, ...
, subnormal numbers are the subset of denormalized numbers (sometimes called denormals) that fill the
underflow gap around zero in
floating-point arithmetic
In computing, floating-point arithmetic (FP) is arithmetic on subsets of real numbers formed by a ''significand'' (a Sign (mathematics), signed sequence of a fixed number of digits in some Radix, base) multiplied by an integer power of that ba ...
. Any non-zero number with magnitude smaller than the smallest positive
normal number
In mathematics, a real number is said to be simply normal in an integer base b if its infinite sequence of digits is distributed uniformly in the sense that each of the b digit values has the same natural density 1/b. A number is said to ...
is ''subnormal'', while ''denormal'' can also refer to numbers outside that range.
Terminology
In some older documents (especially standards documents such as the initial releases of
IEEE 754
The IEEE Standard for Floating-Point Arithmetic (IEEE 754) is a technical standard for floating-point arithmetic originally established in 1985 by the Institute of Electrical and Electronics Engineers (IEEE). The standard #Design rationale, add ...
and
the C language), "denormal" is used to refer exclusively to subnormal numbers. This usage persists in various standards documents, especially when discussing hardware that is incapable of representing any other denormalized numbers, but the discussion here uses the term "subnormal" in line with the 2008 revision of
IEEE 754
The IEEE Standard for Floating-Point Arithmetic (IEEE 754) is a technical standard for floating-point arithmetic originally established in 1985 by the Institute of Electrical and Electronics Engineers (IEEE). The standard #Design rationale, add ...
. In casual discussions the terms ''subnormal'' and ''denormal'' are often used interchangeably, in part because there are ''no'' denormalized IEEE binary numbers outside the subnormal range.
The term "number" is used rather loosely, to describe a particular sequence of digits, rather than a mathematical abstraction; see
Floating-point arithmetic
In computing, floating-point arithmetic (FP) is arithmetic on subsets of real numbers formed by a ''significand'' (a Sign (mathematics), signed sequence of a fixed number of digits in some Radix, base) multiplied by an integer power of that ba ...
for details of how real numbers relate to floating-point representations. "Representation" rather than "number" may be used when clarity is required.
Definition
Mathematical real numbers may be approximated by multiple floating-point representations. One representation is defined as ''normal'', and others are defined as ''subnormal'', ''denormal'', or ''unnormal'' by their relationship to ''normal''.
In a ''normal'' floating-point value, there are no
leading zero
A leading zero is any 0 digit that comes before the first nonzero digit in a number string in positional notation.. For example, James Bond's famous identifier, 007, has two leading zeros. Any zeros appearing to the left of the first non-zero dig ...
s in the
significand
The significand (also coefficient, sometimes argument, or more ambiguously mantissa, fraction, or characteristic) is the first (left) part of a number in scientific notation or related concepts in floating-point representation, consisting of its s ...
(also commonly called mantissa); rather, leading zeros are removed by adjusting the exponent (for example, the number 0.0123 would be written as ). Conversely, a denormalized floating-point value has a significand with a leading digit of zero. Of these, the subnormal numbers represent values which if normalized would have exponents below the smallest representable exponent (the exponent having a limited range).
The significand (or mantissa) of an
IEEE floating-point
The IEEE Standard for Floating-Point Arithmetic (IEEE 754) is a technical standard for floating-point arithmetic originally established in 1985 by the Institute of Electrical and Electronics Engineers (IEEE). The standard addressed many proble ...
number is the part of a floating-point number that represents the
significant digits
Significant figures, also referred to as significant digits, are specific digits within a number that is written in positional notation that carry both reliability and necessity in conveying a particular quantity. When presenting the outcom ...
. For a positive normalised number, it can be represented as ''m''
0.''m''
1''m''
2''m''
3...''m''
''p''−2''m''
''p''−1 (where ''m'' represents a significant digit, and ''p'' is the precision) with non-zero ''m''
0. Notice that for a binary
radix
In a positional numeral system, the radix (radices) or base is the number of unique digits, including the digit zero, used to represent numbers. For example, for the decimal system (the most common system in use today) the radix is ten, becaus ...
, the leading binary digit is always 1. In a subnormal number, since the exponent is the least that it can be, zero is the leading significant digit (0.''m''
1''m''
2''m''
3...''m''
''p''−2''m''
''p''−1), allowing the representation of numbers closer to zero than the smallest normal number. A floating-point number may be recognized as subnormal whenever its exponent has the least possible value.
By filling the underflow gap like this, significant digits are lost, but not as abruptly as when using the ''flush to zero on underflow'' approach (discarding all significant digits when underflow is reached). Hence the production of a subnormal number is sometimes called ''gradual underflow'' because it allows a calculation to lose precision slowly when the result is small.
In
IEEE 754-2008
The Institute of Electrical and Electronics Engineers (IEEE) is an American 501(c)(3) public charity professional organization for electrical engineering, electronics engineering, and other related disciplines.
The IEEE has a corporate office ...
, denormal numbers are renamed ''subnormal numbers'' and are supported in both binary and decimal formats. In binary interchange formats, subnormal numbers are encoded with a
biased exponent of 0, but are interpreted with the value of the smallest allowed exponent, which is one greater (i.e., as if it were encoded as a 1). In decimal interchange formats they require no special encoding because the format supports unnormalized numbers directly.
Mathematically speaking, the normalized floating-point numbers of a given
sign
A sign is an object, quality, event, or entity whose presence or occurrence indicates the probable presence or occurrence of something else. A natural sign bears a causal relation to its object—for instance, thunder is a sign of storm, or me ...
are roughly
logarithm
In mathematics, the logarithm of a number is the exponent by which another fixed value, the base, must be raised to produce that number. For example, the logarithm of to base is , because is to the rd power: . More generally, if , the ...
ically spaced, and as such any finite-sized normal float
cannot include zero. The subnormal floats are a linearly spaced set of values, which span the gap between the negative and positive normal floats.
Background
Subnormal numbers provide the guarantee that addition and subtraction of floating-point numbers never underflows; two nearby floating-point numbers always have a representable non-zero difference. Without gradual underflow, the subtraction ''a'' − ''b'' can underflow and produce zero even though the values are not equal. This can, in turn, lead to
division by zero
In mathematics, division by zero, division (mathematics), division where the divisor (denominator) is 0, zero, is a unique and problematic special case. Using fraction notation, the general example can be written as \tfrac a0, where a is the di ...
errors that cannot occur when gradual underflow is used.
Subnormal numbers were implemented in the
Intel 8087
The Intel 8087, announced in 1980, was the first floating-point coprocessor for the 8086 line of microprocessors. The purpose of the chip was to speed up floating-point arithmetic operations, such as addition, subtraction, multiplication, div ...
while the IEEE 754 standard was being written. They were by far the most controversial feature in the
K-C-S format proposal that was eventually adopted, but this implementation demonstrated that subnormal numbers could be supported in a practical implementation. Some implementations of
floating-point unit
A floating-point unit (FPU), numeric processing unit (NPU), colloquially math coprocessor, is a part of a computer system specially designed to carry out operations on floating-point numbers. Typical operations are addition, subtraction, multip ...
s do not directly support subnormal numbers in hardware, but rather trap to some kind of software support. While this may be transparent to the user, it can result in calculations that produce or consume subnormal numbers being much slower than similar calculations on normal numbers.
IEEE
In
IEEE binary floating-point formats, ''subnormals'' are represented by having a zero exponent field with a non-zero significand field.
[ (Note that the XenuOS documentation uses ''denormal'' where ]IEEE 754
The IEEE Standard for Floating-Point Arithmetic (IEEE 754) is a technical standard for floating-point arithmetic originally established in 1985 by the Institute of Electrical and Electronics Engineers (IEEE). The standard #Design rationale, add ...
uses ''subnormal''.)
No other denormalized numbers exist in the IEEE binary floating-point formats, but they ''do'' exist in some other formats, including the IEEE decimal floating-point formats.
Performance issues
Some systems handle subnormal values in hardware, in the same way as normal values. Others leave the handling of subnormal values to system software ("assist"), only handling normal values and zero in hardware. Handling subnormal values in software always leads to a significant decrease in performance. When subnormal values are entirely computed in hardware, implementation techniques exist to allow their processing at speeds comparable to normal numbers. However, the speed of computation remains significantly reduced on many modern x86 processors; in extreme cases,
instructions involving subnormal operands may take as many as 100 additional clock cycles, causing the fastest instructions to run as much as six times slower.
This speed difference can be a security risk. Researchers showed that it provides a
timing side channel that allows a malicious web site to extract page content from another site inside a web browser.
Some applications need to contain code to avoid subnormal numbers, either to maintain accuracy, or in order to avoid the performance penalty in some processors. For instance, in audio processing applications, subnormal values usually represent a signal so quiet that it is out of the human hearing range. Because of this, a common measure to avoid subnormals on processors where there would be a performance penalty is to cut the signal to zero once it reaches subnormal levels or mix in an extremely quiet noise signal. Other methods of preventing subnormal numbers include adding a DC offset, quantizing numbers, adding a Nyquist signal, etc. Since the
SSE2
SSE2 (Streaming SIMD Extensions 2) is one of the Intel SIMD (Single Instruction, Multiple Data) processor supplementary instruction sets introduced by Intel with the initial version of the Pentium 4 in 2000. SSE2 instructions allow the use of ...
processor extension,
Intel
Intel Corporation is an American multinational corporation and technology company headquartered in Santa Clara, California, and Delaware General Corporation Law, incorporated in Delaware. Intel designs, manufactures, and sells computer compo ...
has provided such a functionality in CPU hardware, which rounds subnormal numbers to zero.
Disabling subnormal floats at the code level
Intel SSE
Intel's C and Fortran compilers enable the (denormals-are-zero) and (flush-to-zero) flags for
SSE by default for optimization levels higher than . The effect of is to treat subnormal input arguments to floating-point operations as zero, and the effect of is to return zero instead of a subnormal float for operations that would result in a subnormal float, even if the input arguments are not themselves subnormal.
clang
Clang () is a compiler front end for the programming languages C, C++, Objective-C, Objective-C++, and the software frameworks OpenMP, OpenCL, RenderScript, CUDA, SYCL, and HIP. It acts as a drop-in replacement for the GNU Compiler ...
and
gcc have varying default states depending on platform and optimization level.
A non-
C99
C99 (previously C9X, formally ISO/IEC 9899:1999) is a past version of the C programming language open standard. It extends the previous version ( C90) with new features for the language and the standard library, and helps implementations mak ...
-compliant method of enabling the and flags on targets supporting SSE is given below, but is not widely supported. It is known to work on
Mac OS X
macOS, previously OS X and originally Mac OS X, is a Unix, Unix-based operating system developed and marketed by Apple Inc., Apple since 2001. It is the current operating system for Apple's Mac (computer), Mac computers. With ...
since at least 2006.
#include
#pragma STDC FENV_ACCESS ON
// Sets DAZ and FTZ, clobbering other CSR settings.
// See https://opensource.apple.com/source/Libm/Libm-287.1/Source/Intel/, fenv.c and fenv.h.
fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV);
// fesetenv(FE_DFL_ENV) // Disable both, clobbering other CSR settings.
For other x86-SSE platforms where the C library has not yet implemented this flag, the following may work:
#include
_mm_setcsr(_mm_getcsr() , 0x0040); // DAZ
_mm_setcsr(_mm_getcsr() , 0x8000); // FTZ
_mm_setcsr(_mm_getcsr() , 0x8040); // Both
_mm_setcsr(_mm_getcsr() & ~0x8040); // Disable both
The and macros wrap a more readable interface for the code above.
// To enable DAZ
#include
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
// To enable FTZ
#include
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
Most compilers will already provide the previous macro by default, otherwise the following code snippet can be used (the definition for FTZ is analogous):
#define _MM_DENORMALS_ZERO_MASK 0x0040
#define _MM_DENORMALS_ZERO_ON 0x0040
#define _MM_DENORMALS_ZERO_OFF 0x0000
#define _MM_SET_DENORMALS_ZERO_MODE(mode) _mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) , (mode))
#define _MM_GET_DENORMALS_ZERO_MODE() (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK)
The default denormalization behavior is mandated by the
ABI, and therefore well-behaved software should save and restore the denormalization mode before returning to the caller or calling code in other libraries.
ARM
AArch32 NEON (SIMD) FPU always uses a flush-to-zero mode, which is the same as . For the scalar FPU and in the AArch64 SIMD, the flush-to-zero behavior is optional and controlled by the bit of the control register – FPSCR in Arm32 and FPCR in AArch64.
One way to do this can be:
#if defined(__arm64__) , , defined(__aarch64__)
uint64_t fpcr;
asm( "mrs %0, fpcr" : "=r"( fpcr )); //Load the FPCR register
asm( "msr fpcr, %0" :: "r"( fpcr , (1 << 24) )); //Set the 24th bit (FTZ) to 1
#endif
Some ARM processors have hardware handling of subnormals.
See also
*
Logarithmic number system
Notes
References
Further reading
*
* See also various papers on
William Kahan
William "Velvel" Morton Kahan (born June 5, 1933) is a Canadian mathematician and computer scientist, who is a professor emeritus at University of California, Berkeley. He received the Turing Award in 1989 for "his fundamental contributions to nu ...
's web sit
for examples of where subnormal numbers help improve the results of calculations.
{{DEFAULTSORT:Subnormal Number
Computer arithmetic
Articles with example C code