How can I manually set the bit value of a float that equates to NaN?
c, floating-point, nan
Solution
You may be able to control the 'payload' bits by passing appropriate strings to the C99 `nan`, `nanf`, `nanl` functions, but these will only generate quiet NaNs, and the interpretation of the string is left unspecified (most implementations treat it as a hexadecimal number).
Alternatively, use a union:
#ifndef __STDC_IEC_559__
#error "This program requires IEEE floating point arithmetic"
#endif
#include <stdint.h>
#include <assert.h>
static_assert(sizeof(float) == sizeof(uint32_t),
"This program requires float to be 32 bits exactly");
float nanf_with_payload_bits(uint32_t payload)
{
if (payload & 0x7FA00000) abort();
union ieee_single {
float f;
uint32_t i;
} nan;
nan.i = 0x7FA00000 | payload;
return nan.f;
}
Writing to one member of a union and then reading from another, when both types are exactly the same size, does NOT provoke undefined behavior in C99+errata. (It was undefined behavior in C89, but most compilers defined it to do what you would expect. It may still be undefined behavior in C++, I'm not sure; however, again, most compilers define it to do what you would expect.)
If you use this function to create signaling NaNs, be aware that their behavior is explicitly left undefined in C99/C11 Annex F.
DO NOT attempt to break down the `i` component of the union into a structure with bit-fields. The memory layout of bit-fields within a structure is partially implementation-defined and partially unspecified, and in particular a sequence of bit-fields is not necessarily packed into a word in the same order as the CPU endianness (or, indeed, properly packed at all).
Standards citations (all C99):
- this use of a union is only unspecified behavior: 6.2.6.1p7; J.1
- the layout of bitfields within a structure is unpredictable: 6.2.6.1p1,2; 6.7.2.1p10,11,13; J.3.9
- the behavior of signaling NaNs is undefined: F.2.1
Problem
I'm trying to run some tests with conversions and castings of floats to other types and I want to set my float variable to different values of nan. "a bit-wise example of a IEEE floating-point standard single precision (32-bit) NaN would be: s111 1111 1axx xxxx xxxx xxxx xxxx xxxx where s is the sign (most often ignored in applications), a determines the type of NaN, and x is an extra payload (most often ignored in applications). If a = 1, it is a quiet NaN; if a is zero and the payload is nonzero, then it is a signaling NaN" Basically I want to find a way to set the payload or xxxx's of the representation. Is there any way to do this in c?