Math.sqrt(NaN) behaves differently on windows and linux

From what I'm reading at
http://www.opengroup.org/onlinepubs/009695399/functions/sqrt.html, it
appears that in this case, Windows is, in fact, doing the right thing
(though see below). From the text:

"For finite values of x < -0, a domain error shall occur, and either a
NaN (if supported), or an implementation-defined value shall be
returned."

It looks to me like *nix is only returning NaN, but isn't actually
raising an error while Windows is raising an error, but is not returning
NaN.

begin
   x = Math.sqrt(0.0/0.0)
rescue Errno::EDOM => err
   puts "X is: #{x}" # Should be NaN
   puts "Error: #{err}"
   raise
end

I'd say this is a bug all the way around.

Regards,

Dan

···

-----Original Message-----
From: Dave Baldwin [mailto:dave.baldwin@3dlabs.com]
Sent: Monday, April 04, 2005 6:50 AM
To: ruby-talk ML
Subject: Re: Math.sqrt(NaN) behaves differently on windows and linux

On 4 Apr 2005, at 12:48, Geert Fannes wrote:

> Hello, the following statement gives different results on
windows and
> linux:
> Linux:
>
> irb(main):003:0> Math.sqrt(0.0/0.0)
>
> * NaN
>
Mac OS X gives this result.

> Windows:
>
> irb(main):002:0> Math.sqrt(0.0/0.0)
>
> Errno::EDOM: Domain error - sqrt
>
> from (irb):2:in `sqrt'
>
> from (irb):2
>
> I guess this is not as it should be. Which is the correct way to
> handle NaNs?
>
> How can I generate NaN without using the trick 0.0/0.0. Why
does 0/0
> give a ZeroDivisionError and 0.0/0.0 a NaN
>
>
0/0 is integer division and all bit patterns are used.
0.0/0.0 is floating point division and for IEEE floating
point numbers
the result is defined by the standard to be NaN. Bit
patterns has been
reserved to all information like this to be encoded in the number.

Can't help you with what Windows is doing or how to generate
a NaN more
cleanly from Ruby. It would be very simple to generate one
as part of
a C extension.

Dave.

>
> Greetings,
>
> Geert Fannes.

From what I'm reading at
http://www.opengroup.org/onlinepubs/009695399/functions/sqrt.html, it
appears that in this case, Windows is, in fact, doing the right thing
(though see below). From the text:

"For finite values of x < -0, a domain error shall occur, and either a
NaN (if supported), or an implementation-defined value shall be
returned."

It seems to me that the the relevant part in the text is:

"If x is NaN, a NaN shall be returned."

So the *nix implementation is correct and the Windows one is not.

It looks to me like *nix is only returning NaN, but isn't actually
raising an error while Windows is raising an error, but is not returning
NaN.

Well, there is a problem here between the way C and Ruby raise error. In
C, the eerno variable is set and a specific value is returned. In Ruby,
when an error is raised, the call doesn't return and the call stack is
traversed to find the next rescue clause. So in Ruby, it will return NaN
or raise an error, but never both.

Guillaume.

···

On Tue, 2005-04-05 at 02:50 +0900, Berger, Daniel wrote:

Guillaume Marcais wrote:

> From what I'm reading at
> sqrt,

it

> appears that in this case, Windows is, in fact, doing the right

thing

> (though see below). From the text:
>
> "For finite values of x < -0, a domain error shall occur, and

either a

> NaN (if supported), or an implementation-defined value shall be
> returned."

It seems to me that the the relevant part in the text is:

"If x is NaN, a NaN shall be returned."

So the *nix implementation is correct and the Windows one is not.

I think it's open for debate. It causes a ZeroDivision error on both
Perl and Python if we want to look at what other languages do.

> It looks to me like *nix is only returning NaN, but isn't actually
> raising an error while Windows is raising an error, but is not

returning

> NaN.

Well, there is a problem here between the way C and Ruby raise error.

In

C, the eerno variable is set and a specific value is returned. In

Ruby,

when an error is raised, the call doesn't return and the call stack

is

traversed to find the next rescue clause. So in Ruby, it will return

NaN

or raise an error, but never both.

Guillaume.

Yeah, I wasn't thinking. It would be kinda neat if we could (though I
have no idea how that would be implemented).

What about a compromise where an error is raised, and "NaN" is included
in part of the error message, e.g.

Errno::EDOM: NaN (sqrt)

Or something like that?

Dan

PS - I think this is my 4th attempted reply - if a bunch of similar
messages show up later, it's my mail server acting up.

···

On Tue, 2005-04-05 at 02:50 +0900, Berger, Daniel wrote:

It seems to me that the the relevant part in the text is:

"If x is NaN, a NaN shall be returned."

So the *nix implementation is correct and the Windows one is not.

I think it's open for debate. It causes a ZeroDivision error on both
Perl and Python if we want to look at what other languages do.

Well, I should have said: "it behaves according to what the quoted article specifies".

Looking at the Ruby code, Ruby relies on the the OS implementation of the mathematic library. So here it is not Ruby that generate the error or Nan in the first, but the OS. So Windows and *nix disagree apparently on the behavior.

So the question is: should Ruby rely on the system for its mathematical computation, or should it provide an abstraction layer to offer a consistent behavior across platforms?

Yeah, I wasn't thinking. It would be kinda neat if we could (though I
have no idea how that would be implemented).

What about a compromise where an error is raised, and "NaN" is included
in part of the error message, e.g.

Errno::EDOM: NaN (sqrt)

Or something like that?

Sure, sounds good. But I am not in the right person to make that decision though.

Guillaume.

···

Le 4 avr. 05, à 16:14, Daniel Berger a écrit :