> -----Original Message-----
> From: Nicholas Clark (via RT)
> [mailto:[EMAIL PROTECTED]
> Sent: Thursday, October 02, 2003 9:04 AM
> To: Adam Thomason
> Subject: Re: [perl #24088] [PATCH] Parrot on AIX
>
>
> On Thu, Oct 02, 2003 at 11:52:48AM -0400, Dan Sugalski wrote:
> > On Thu, 2 Oct 2003, Nicholas Clark wrote:
> >
> > > On Thu, Oct 02, 2003 at 10:35:29AM +0200, Leopold Toetsch wrote:
> > > > Adam Thomason <[EMAIL PROTECTED]> wrote:
> > >
> > > > > The one remaining test failure in 'make test' is
> op/number test 10,
> > > > > the second part of which computes mod(0.0,3.0). The
> expected value is
> > > > > 0.0, but I see -0.0. However, given the definition of
> > > > > mod(x,y)=x-y*floor(x/y), this case reduces to
> 0.0-0.0*0.0, which could
> > > > > justify -0.0. Perhaps the test can be relaxed
> somehow to accomodate
> > > > > minus-zero semantics.
> > > >
> > > > Sounds correct, yes.
> > >
> > > Relaxing that test doesn't feel right to me. Partly in
> black box terms
> > > because I would expect putting strictly non-negative
> values into mod
> > > shouldn't create a negative zero, and partly in terms of
> that implementation
> > > because I thought that negative zero was only allowed to
> arise as the result
> > > of division and multiplication, never from addition or
> *in this case)
> > > subtraction.
> >
> > In this case, while I think it's truly bizarre (negative
> zero, that is),
> > since 0 and -0 are exactly equivalent, arguably they're
> both OK, and thus
> > should both be accepted.
>
> Hrrm. Which bit of code is actually generating a negative zero?
Turns out the IBM compiler is being aggressively helpful here and inserting a
multiply-add instruction. For instance:
main(){
double x=0.0, y=1.0, z=0.0;
printf( "%f\n", x - y * z );
}
Compiled with xlc (no optimization), the above print -0.0, while gcc prints 0.0.
However, passing the -qfloat=nomaf flag (which disables multiply-add injection) to xlc
gets it to print 0.0. Looking at the assembly produced with and without the flag
respectively, it's transforming
fm fp2,fp2,fp3
fs fp1,fp1,fp2
into
fnms fp1,fp2,fp3,fp1
which apparently can introduce a minus zero. I wouldn't have expected this with no
optimization, but it seems legitimate to me. The triggering code is "n2 - n3 *
floor(n2 / n3)" on utils.c:64. So if preserving the obviousness of mod(>=0,>=0)>=0 is
important, that probably ought to be explicitly ensured in floatval_mod.
Adam Thomason