After a brief discussion on IRC, it seems like PMCs are the proper way
to handle this. Specifically, three new PMC types: NaN, Inf, and
NegInf. So here's what I'd like to do:
1) Implement these three types as core PMCs that work like Tcl wants them too.
2) When another language wants something to work in a way that
differs from what's implemented, implement new dynpmcs for one of the
two languages.
In other words, implement them so they work with Tcl and let them grow
organically.
Does this sound good? (Chip? Allison?)
--
Matt Diephouse
http://matt.diephouse.com
> don't forget about negative-not-a-number, and the quiet (or signaling)
Ah yes. that oxymoron.
I've never yet seen the reasons for why it exists at all. Does anyone have
a URL?
Nicholas Clark
Ron Blaschke <mailin...@rblasch.org> did some work in stringifying these
things, see [perl #38887]
http://en.wikipedia.org/wiki/IEEE_754
To summarize, if all the exponential bits are set, you get one of these odd
ducks. If the mantissa is zero, then you get +/- Inf, based on the sign
bit. If the mantissa is non-zero, you get a NaN, obviously there's lots of
ways ot make NaN's (if the sign bit is set, Solaris prints -NaN).
Fortunately, this is something you can rely on across architectures. Only
thing is you need to know wheather it's big or little-endian.
The signaling NaN vs the non-signaling is architecture dependent, the
following link discusses AMD and Intel
http://en.wikipedia.org/wiki/NaN
It seems like you shouldn't need PMC for this, just the N-thingy (sorry my
parrot is rusty). That is, these guys can be represented purely by floats
or doubles -- unless, of course, we're supporting non-ieee-754 machine
architecture.
--
Bill Coffman
~~~_\\\|/
~~~-(@ @)
=oOO=(_)==OOo===
I am wondering if this NaN != NaN property could be used for the isnan
and finite tests, like so:
int
Parrot_math_isnan(double x)
{
return x != x;
}
int
Parrot_math_finite(double x)
{
return (!Parrot_math_isnan(x - x));
}
That is, if "x != x" it's a NaN. If x is finite, "x - x" should yield
something close to 0. Otherwise, "Inf - Inf" or "NaN - NaN", it's NaN.
Is this not portable enough? Is it better to look at the bits directly?
Ron
'x - x' should always yield precisely 0 -
http://docs.sun.com/source/806-3568/ncg_goldberg.html#929 says "The IEEE
standard uses denormalized numbers, which guarantee [...] x = y <=> x -
y = 0", and later states "x - x = +0 for all x [...] Unless the rounding
mode is round toward -Inf, in which case x - x = -0". (Except when x is
+/-Inf or NaN, when it should give NaN.)
> Is this not portable enough? Is it better to look at the bits directly?
It doesn't work nicely with optimisers (or at least with MSVC's).
Parrot_math_isnan seems to be handled correctly, but Parrot_math_finite
has problems:
Using VS2003 /O1, it does compile into a call to Parrot_math_isnan, but
with the argument 0.0 (via 'fldz') rather than calculating x-x.
Using VS2003 /O2, it does:
?Parrot_math_finite@@YAHN@Z PROC NEAR
mov eax, 1
ret 0
?Parrot_math_finite@@YAHN@Z ENDP
Using VS2003 /O2 plus /Op ("improve floating-pt consistency") it does
get the correct answer.
Using VS2005 /O0 to /O2, it does get the correct answer by default. But
adding /fp:fast makes it the same as the VS2003 behaviour. (The
documentation says /fp:precise enables behaviour where "Expression
optimizations that are invalid for special values (NaN, +infinity,
-infinity, +0, -0) will not be allowed. The optimizations x-x => 0, x*0
=> 0, x-0 => x, x+0 => x, and 0-x => -x are all invalid for various
reasons (see IEEE 754 and the C99 standard)", but those optimisations
are allowed under /fp:fast because most people care about speed more
than predictable/correct output.)
It seems like the only way to stay safe is to work around the optimiser,
presumably by testing bits or using library functions or writing
assembly code (e.g. with 'fxam' on x86).
>
> Ron
>
--
Philip Taylor
phi...@zaynar.demon.co.uk
>> Is this not portable enough? Is it better to look at the bits directly?
[great stuff snipped]
> It seems like the only way to stay safe is to work around the optimiser,
> presumably by testing bits or using library functions or writing
> assembly code (e.g. with 'fxam' on x86).
Thanks a lot for sharing your deep insights, Philip. Judging from
Bill's and your input it's probably best to look at the bits directly.
Too bad, the two lines solution would have been really tempting. Resist
the dark side of code one must. ;-)
Thanks,
Ron