Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if a float is not a number

Tags:

c++

This code is from UE4 and I have some trouble understanding it.

static FORCEINLINE bool IsNaN( float A ) 
{
    return ((*(uint32*)&A) & 0x7FFFFFFF) > 0x7F800000;
}

(uint32 is just an unsigned int)

The first part is interpreting a float as an uint32, that is the easy part but why bitwise and it with 0x7FFFFFFF? What are the last 4 bits telling us and why do we compare the result with 0x7F800000?

like image 366
Maik Klein Avatar asked Jul 08 '26 07:07

Maik Klein


2 Answers

This definition follows the NaN definition provided in IEEE 754 standard.

In IEEE 754 standard-conforming floating point storage formats, NaNs are identified by specific, pre-defined bit patterns unique to NaNs.

0x7FFFFFFF is the largest value, that can be represented on 31 bits. In this case, it simply ignores the bit sign, because:

The sign bit does not matter.

0x7F800000 is the mask for bits of the exponential field.

For example, a bit-wise IEEE floating-point standard single precision (32-bit) NaN would be: s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx where s is the sign (most often ignored in applications) and x is non-zero (the value zero encodes infinities).

Where s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx with s = 0 (ignored by anding with 0x7FFFFFFF) and x = 0 is equal to 0x7F800000.

operator > is used, because if any bit in the significand is set (any x), resulting value will be greater than 0x7F800000.

And why should it be set? Because:

The state/value of the remaining bits [...] are not defined by the standard except that they must not be all zero.

Source: NaN on Wikipedia.

like image 107
Mateusz Grzejek Avatar answered Jul 10 '26 21:07

Mateusz Grzejek


This is the definition a NaN. You can read this in detail on wikipedia.
0x7FFFFFFF is used because the sign bit does not matter in the check.
The definition says that for a nan the exponential field is filled with ones and some non-zero number is in the significand.
0x7F80000 this is the bit mask for the exponential field. So if a bit is set in the significand the the number must be larger than 0x7F800000

Note that is assumes that a sizeof(float) == 4.

like image 34
mkaes Avatar answered Jul 10 '26 20:07

mkaes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!