Re: Re: Re: math broken on mips

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Zhang,

>    a quick example:
>  main()
> {
>    float t,zero=0.0;
>    t = 0.0/0.0;
>    printf("t=%08lx\n",*(unsigned long*)&t); (0x7fc00000)
>    t = zero/zero;
>    printf("t=%08lx\n",*(unsigned long*)&t); (0x7fbfffff)
> }
> 
> you should see different output,because the first one is optimized
> by gcc to a QNaN,but it's signalling for MIPS.

On my RedHat 7.1 x86 machine you get something of the same kind.  The
constant expression ("0.0/0.0") is always computed at compile time,
but the "zero/zero" is only resolved as a constant once you turn on
the optimiser.

So I see two different values printed without optimisation, but the
same value twice with -O2.

(Note that the 0.0/0.0 will be computed as a double, while zero/zero
will be computed as a float - but I don't think that makes any
difference in this case).

A floating point purist would say that the compiler should never try
to propagate floating point constants where the calculation might
produce any exception or exceptional result.

That's standards-correct, but unacceptable in practice.  If I write

  float pi = 3.1415926535897932384626433832795029;

the decimal->binary conversion will be inexact and might produce an
exception (if that flag is set: it almost never is, but the compiler
doesn't know that).  But I'll be annoyed if my compiler doesn't
generate a binary floating point value for 'pi' at compile time.

Once you open this door and allow the compiler to work on some
floating point constants, life gets tougher.  It might be a good rule
that if an expression produces an exceptional value (NaN, infinity),
you leave it to run-time... but it may mean some ugly back-tracking.

In this case gcc for x86 (and MIPS) has had no inhibitions: it's just
seen a constant expression and reduced it.  With no way to predict the
FP mode settings which will be in effect it has no way of knowing what
kind of exceptional result to produce in this case.  

The compiler is now kind of outside the specs: but it's still better
style to produce a signalling NaN (anyone who wanted their NaNs quiet
probably has exceptions turned off so won't know the difference;
anyone who didn't want their NaNs quiet should probably get an
exception).  But frankly, it's not important.

In expecting floating point maths to "just work" in corner cases,
you're expecting too much.  If you want to be appropriately
frightened, here's a paper I came across fairly recently - David
Goldberg's "What Every Computer Scientist should Know about Floating
Point":

  http://cch.loria.fr/documentation/IEEE754/ACM/goldberg.pdf

--
Dominic Sweetman
Algorithmics Ltd
The Fruit Farm, Ely Road, Chittering, CAMBS CB5 9PH, ENGLAND
phone +44 1223 706200/fax +44 1223 706250/direct +44 1223 706205
http://www.algor.co.uk


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux