background image

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.