Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Inf and NaN

7 views
Skip to first unread message

Matt Diephouse

unread,
Jul 31, 2006, 12:58:51 AM7/31/06
to parrot-...@perl.org
In the recent push to implement all of Tcl's [expr] command, Tcl has
come to the point where it needs to understand Inf and NaN.

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

Jerry Gay

unread,
Jul 31, 2006, 1:45:29 AM7/31/06
to ma...@diephouse.com, parrot-...@perl.org
On 7/30/06, Matt Diephouse <mdd...@gmail.com> wrote:
> In the recent push to implement all of Tcl's [expr] command, Tcl has
> come to the point where it needs to understand Inf and NaN.
>
> 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:
>
don't forget about negative-not-a-number, and the quiet (or signaling)
alternatives; you're not specific as to which behavior you expect from
these, so i can't be more specific as to which behavior you've failed
to represent. i won't speak to the solution, but i do want to point
out that the problem space includes numerous (though countable)
numeric error conditions.
~jerry

Nicholas Clark

unread,
Jul 31, 2006, 6:53:08 AM7/31/06
to jerry gay, ma...@diephouse.com, parrot-...@perl.org
On Sun, Jul 30, 2006 at 10:45:29PM -0700, jerry gay wrote:

> 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

Bill Coffman

unread,
Jul 31, 2006, 11:35:02 AM7/31/06
to jerry gay, ma...@diephouse.com, parrot-...@perl.org
NegNan doesn't exist, except as a fluke of the representation (see link for
how they are represented). A -NaN is the same as a NaN. They both fail all
comparison tests, even NaN == NaN is false (unless your compiler optimizes
the comparison out). Only difference is the way they are stringified, which
should be "NaN", but stringification of NaN is non-standard. Solaris
compilers will print "-NaN", but gcc only prints "nan". Microsoft compiler
prints strange stuff.

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===

Ron Blaschke

unread,
Aug 1, 2006, 3:17:18 AM8/1/06
to parrot-...@perl.org
Bill Coffman wrote:
> NegNan doesn't exist, except as a fluke of the representation (see link for
> how they are represented). A -NaN is the same as a NaN. They both fail
> all
> comparison tests, even NaN == NaN is false (unless your compiler optimizes
> the comparison out). Only difference is the way they are stringified,
> which
> should be "NaN", but stringification of NaN is non-standard. Solaris
> compilers will print "-NaN", but gcc only prints "nan". Microsoft compiler
> prints strange stuff.

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

Philip Taylor

unread,
Aug 1, 2006, 9:40:55 AM8/1/06
to r...@rblasch.org, parrot-...@perl.org
Ron Blaschke wrote on 01/08/2006 08:17:
>
> 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.

'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

Ron Blaschke

unread,
Aug 1, 2006, 11:16:54 AM8/1/06
to Philip Taylor, parrot-...@perl.org
Philip Taylor wrote:
> Ron Blaschke wrote on 01/08/2006 08:17:
>>
>> I am wondering if this NaN != NaN property could be used for the isnan
>> and finite tests, like so:
[snip]

>> 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

0 new messages