In GLSL, what is the difference between isnan(x)
and !(x == x)
?
1 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.
-
$\begingroup$ 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 $\endgroup$– TomasApr 25, 2019 at 15:25
isnan
; C++11 hasstd::isnan
. Java hasJava.lang.Double.isNan
. C# hasDouble.IsNan
. IEEE-754 even has a specific predicate calledisNaN
. 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. $\endgroup$