<p>IEEE-754 defines the <code>isNaN</code> property, which determines if a value is NaN. However, it is also defined to be a non-signaling operation; calling <code>isNaN</code> on an sNaN will never result in a signaled failure. By contrast, equality testing may signal when given sNaN values.</p>

<p>Now, GLSL explicitly states that signaling doesn't matter:</p>

<blockquote>
  <p>Support for signaling NaNs is not required and exceptions are never raised.</p>
</blockquote>

<p>But of course, there's also the fact that <code>isnan</code> is a vector function, while <code>!(x == x)</code> only works on scalars. So if you want to test if any of the elements of a <code>vec3</code> are NaN, you can do <code>any(isnan(some_vec))</code>, while the equality-testing equivalent would be even more obtuse and verbose: <code>any(not(equal(some_vec, some_vec)))</code>.</p>

<p>And all of that ignores the simple usability reasons for having <code>isnan</code>. <code>!(x == x)</code> is an idiom which must be learned, while <code>isnan</code> is an easily looked up function whose name tells you want it does. After all, most users of floats tend to forget about NaN, so such an expression seems like a tautology, while "isnan" explicitly reminds such people that NaNs are a real thing and they are reading code where that fact is important.</p>

<p>Also, as previously stated, <code>isNaN</code> is a property defined by IEEE-754. It is also a function provided by the standard libraries of C99, C++11, Java, C#, Swift, Go, JavaScript, and I can keep going, but I think my point is clear.</p>

CC BY-SA 4.0
2019-04-25T15:25:44.623Z
Great!
So other languages actually have a difference between the two approaches.
And glsl has the function just to mimic those languages, even if there is no difference (apart from the readability point).
Thanks for the explanation :D
Tomas
CC BY-SA 4.0
2019-04-25T15:10:08.283Z
2020-03-08T18:37:08.140Z
2020-03-08T18:37:08.140Z
Nicol Bolas
<p>In GLSL, what is the difference between <code>isnan(x)</code> and <code>!(x == x)</code>?</p>

CC BY-SA 4.0
2019-04-25T13:42:06.533Z
You mean, besides the fact that one of these is self-explanatory and the other appears to be gibberish?
Nicol Bolas
CC BY-SA 4.0
2019-04-25T14:49:42.043Z
@NicolBolas comparison with self is the usual way to test for nan with standard conforming floats and glsl is, as far as I know, required to abide by them. Therefore I consider adding another function as superfluous (and confusing), unless (or especially if) it has a different behavior.
Tomas
CC BY-SA 4.0
2019-04-25T14:57:49.790Z
"Usual" is in the eye of the beholder. C99 has `isnan`; C++11 has `std::isnan`. Java has `Java.lang.Double.isNan`. C# has `Double.IsNan`. IEEE-754 even has a specific predicate called `isNaN`. It seems to me that those relying on `!(x==x)` are due to using standard libraries that are deficient, not because it is "usual". An explicit function is always easier to understand than an idiom that must be learned.
Nicol Bolas
CC BY-SA 4.0
2019-04-25T15:09:57.807Z
I did not know that such functions were so common. Thanks for mentioning them.
Can I conclude that the behavior is indeed the same?

By one's personal experience, is it possible that the two methods behave differently on some devices?
Tomas
<glsl>
Difference between isnan and comparison to self
Tomas
# Difference between isnan and comparison to self

(Asked by: username_0 on 2019-04-25)

In GLSL, what is the difference between `isnan(x)` and `!(x == x)`?

**Tags:** glsl

> **Comments:**
> **username_1**: You mean, besides the fact that one of these is self-explanatory and the other appears to be gibberish?  
> **username_0**: @username_1 comparison with self is the usual way to test for nan with standard conforming floats and glsl is, as far as I know, required to abide by them. Therefore I consider adding another function as superfluous (and confusing), unless (or especially if) it has a different behavior.  
> **username_1**: "Usual" is in the eye of the beholder. C99 has `isnan`; C++11 has `std::isnan`. Java has `Java.lang.Double.isNan`. C# has `Double.IsNan`. IEEE-754 even has a specific predicate called `isNaN`. It seems to me that those relying on `!(x==x)` are due to using standard libraries that are deficient, not because it is "usual". An explicit function is always easier to understand than an idiom that must be learned.  
> **username_0**: I did not know that such functions were so common. Thanks for mentioning them. Can I conclude that the behavior is indeed the same?  By one's personal experience, is it possible that the two methods behave differently on some devices?  

---

## 1 answers

### Answer by username_1 on 2019-04-25. Score: 5 | Accepted answer

IEEE-754 defines the `isNaN` property, which determines if a value is NaN. However, it is also defined to be a non-signaling operation; calling `isNaN` on an sNaN will never result in a signaled failure. By contrast, equality testing may signal when given sNaN values.

Now, GLSL explicitly states that signaling doesn't matter:

> Support for signaling NaNs is not required and exceptions are never raised.

But of course, there's also the fact that `isnan` is a vector function, while `!(x == x)` only works on scalars. So if you want to test if any of the elements of a `vec3` are NaN, you can do `any(isnan(some_vec))`, while the equality-testing equivalent would be even more obtuse and verbose: `any(not(equal(some_vec, some_vec)))`.

And all of that ignores the simple usability reasons for having `isnan`. `!(x == x)` is an idiom which must be learned, while `isnan` is an easily looked up function whose name tells you want it does. After all, most users of floats tend to forget about NaN, so such an expression seems like a tautology, while "isnan" explicitly reminds such people that NaNs are a real thing and they are reading code where that fact is important.

Also, as previously stated, `isNaN` is a property defined by IEEE-754. It is also a function provided by the standard libraries of C99, C++11, Java, C#, Swift, Go, JavaScript, and I can keep going, but I think my point is clear.

> **Comments:**
> **username_0**: Great! So other languages actually have a difference between the two approaches. And glsl has the function just to mimic those languages, even if there is no difference (apart from the readability point). Thanks for the explanation :D  

---

