FLoat NAN is uneqal to itself, why?

 

I just came accross an interesting effect and wanted to know why this is so.

I am not sure if this is considered a bug, but here is the code to reproduce:

static const union flt_conv_flt_nan     { float f;  uint u;     flt_conv_flt_nan()      : u(0xFFC00001) {}; }           flt_nan;

#define FLT_NAN         flt_nan.f


union test { float f; uint u; } test_val;

test_val.f = FLT_NAN;

if(FLT_NAN == FLT_NAN)
{ printf("TRUE1"); }

if(test_val.f == FLT_NAN)
{ printf("TRUE2"); }

if(test_val.f == test_val.f)
{ printf("TRUE3"); }

if(test_val.u == test_val.u)
{ printf("TRUE4"); }

The output will only be "TRUE4"

Why is this so, shouldnt they be eqal?

 
I figured.

It's by design. NaN is unequal to everything,also to itself, by definition.



 
Dominik Christian Egert #:
I figured.

It's by design. NaN is unequal to everything,also to itself, by definition.



double.NaN != double.NaN (always)

 
Behavior depends on how compiler generates math with doubles. There are two models Fast and Precise.
MQL uses Precise model, it means each double comparison takes 3 CPU instructions: 1 compare and 2 conditional jumps (first jump if condition is not true, second jump if NaNs detected)
Fast model is only one jump - if condition is true, so this model does not detect NaNs and expression (x==Nan && x!=Nan) is true
 
Because that identity is not fulfilled, we have MathIsValidNumber() and MathClassify() to detect NaNs
 
Ilyas #:
Behavior depends on how compiler generates math with doubles. There are two models Fast and Precise.
MQL uses Precise model, it means each double comparison takes 3 CPU instructions: 1 compare and 2 conditional jumps (first jump if condition is not true, second jump if NaNs detected)
Fast model is only one jump - if condition is true, so this model does not detect NaNs and expression (x==Nan && x!=Nan) is true

Good to know this info.

Thanks

Reason: