On Wed, 16 May 2018 05:38:29 -0700 (PDT)
Alexandru <
alexandr...@meshparts.de> wrote:
> [...]
> Still intresting is that I get -NaN as a result to the division 0/0
> in C.
Most computers use the IEEE-754 float format.
Without a lot of details, such a number consists of a signum bit, E
exponent bits and M manissa bits. If all bits of the exponent are set
but all bits of the mantissa are 0, that is infinity and the signum bit
indicates its sign. When all the exponent bits are 1 but not all the
mantissa bits are 0, then you have a NaN (and some of the bits in the
mantissa may give you some additional info). For a NaN the meaning of
the signum bit is not defined and it can be in either state.
If it happens to be set and the print routine you use examines the
signum bit first, then you will get a "-" printed before the rest
realises that you have a NaN. Nevertheless, a NaN is a NaN.
By the way, IEEE comparison is a tricky business. For example,
-0 equals +0, which you would expect. You would also expect that +inf
does not equal to any finite number or -inf. It is a bit more
surprising that +inf equals to +inf. Why is it surprising? Because inf
is used to indicate overflow and two wrongs should not make a right, if
you get my drift. Nevertheless, the standard specifies that infinities
with the same sign compare equal.
However, and this is actually important in your case, the standard also
specifies that if an operand of a comparison is NaN, then the
comparison must evaluate false, except if it is for "not equal" in
which case it must return true. Try this:
#include <stdio.h>
#include <math.h>
int main( void )
{
double a = nan(); // Std. math function, returning a NaN
printf( "%f %d\n", a, a == a );
return 0;
}
or, if you prefer Tcl, this:
set a NaN
puts "$a [expr { $a == $a }]"
Lo and behold, a is not equal to itself.
So comparing the return value against NaN does *not* tell you whether
the returned value is NaN or not.
Now, in C there's a handy function, isnan(x) which, as its name
implies, tells you whether x is NaN. Alas, this doesn't exist in Tcl
(at least I couldn't find it) and if you pass a NaN to anything in
expr, it will complain.
In fact, if you pass it -NaN it will spit the dummy, as that parses to
unitary minus operator followed by NaN and expr refuses to evaluate any
operator other than a comparison one on a NaN.
But this is Tcl, everything is a string, so string compare should work,
right? Indeed,
if { [string equal $x "NaN"] || [string equal $x "-NaN"] } {}
does indeed work.
Note, however, that
if { "$x" == "NaN" || "$x" == "-NaN" } {}
does *not* work! Whether 'x' is converted to string to be compared
against the string "NaN" or the string "NaN" is converted to double to
be compared against the value of 'x' is up to the interpreter. You must
use a solution which forces the double to be converted to its string
representation and performs string comparison.
Regards,
Zoltan
--
Zoltán Kócsi
Bendor Research Pty. Ltd.