4-16 Vol. 1
DATA TYPES
4.8.3.5
Operating on SNaNs and QNaNs
When a floating-point operation is performed on an SNaN and/or a QNaN, the result of the operation is either a
QNaN delivered to the destination operand or the generation of a floating-point invalid operation exception,
depending on the following rules:
•
If one of the source operands is an SNaN and the floating-point invalid-operation exception is not masked (see
Section 4.9.1.1, “Invalid Operation Exception (#I)”), then a floating-point invalid-operation exception is
signaled and no result is stored in the destination operand.
•
If either or both of the source operands are NaNs and floating-point invalid-operation exception is masked, the
result is as shown in Table 4-7. When an SNaN is converted to a QNaN, the conversion is handled by setting the
most-significant fraction bit of the SNaN to 1. Also, when one of the source operands is an SNaN, the floating-
point invalid-operation exception flag is set. Note that for some combinations of source operands, the result is
different for x87 FPU operations and for SSE/SSE2/SSE3/SSE4.1 operations. Intel AVX follows the same
behavior as SSE/SSE2/SSE3/SSE4.1 in this respect.
•
When neither of the source operands is a NaN, but the operation generates a floating-point invalid-operation
exception (see Tables 8-10 and 11-1), the result is commonly a QNaN FP Indefinite (Section 4.8.3.7).
Any exceptions to the behavior described in Table 4-7 are described in Section 8.5.1.2, “Invalid Arithmetic Operand
Exception (#IA),” and Section 11.5.2.1, “Invalid Operation Exception (#I).”
4.8.3.6
Using SNaNs and QNaNs in Applications
Except for the rules given at the beginning of Section 4.8.3.4, “NaNs,” for encoding SNaNs and QNaNs, software is
free to use the bits in the significand of a NaN for any purpose. Both SNaNs and QNaNs can be encoded to carry and
store data, such as diagnostic information.
By unmasking the invalid operation exception, the programmer can use signaling NaNs to trap to the exception
handler. The generality of this approach and the large number of NaN values that are available provide the sophis-
ticated programmer with a tool that can be applied to a variety of special situations.
For example, a compiler can use signaling NaNs as references to uninitialized (real) array elements. The compiler
can preinitialize each array element with a signaling NaN whose significand contains the index (relative position) of
Table 4-7. Rules for Handling NaNs
Source Operands
Result
1
SNaN and QNaN
x87 FPU — QNaN source operand.
SSE/SSE2/SSE3/SSE4.1/AVX — First source operand (if this operand is an
SNaN, it is converted to a QNaN)
Two SNaNs
x87 FPU—SNaN source operand with the larger significand, converted into a
QNaN
SSE/SSE2/SSE3/SSE4.1/AVX — First source operand converted to a QNaN
Two QNaNs
x87 FPU — QNaN source operand with the larger
significand
SSE/SSE2/SSE3/SSE4.1/AVX — First source operand
SNaN and a floating-point value
SNaN source operand, converted into a QNaN
QNaN and a floating-point value
QNaN source operand
SNaN (for instructions that take only one operand)
SNaN source operand, converted into a QNaN
QNaN (for instructions that take only one operand)
QNaN source operand
NOTE:
1. For SSE/SSE2/SSE3/SSE4.1 instructions, the first operand is generally a source operand that becomes the destination operand. For
AVX instructions, the first source operand is usually the 2nd operand in a non-destructive source syntax. Within the Result column,
the x87 FPU notation also applies to the FISTTP instruction in SSE3; the SSE3 notation applies to the SIMD floating-point instruc-
tions.