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

Re: Gcc prints NAN for floats that are not NANs



"Dr. Daniel Mashao" <daniel@comgate.ee.uct.ac.za> writes:

> I could never reproduce the problem on a smaller code. If I put just one
> extra printf() statement the problem disappears and appears elsewhere in
> the code. Here is the code
> 
> #define SCALE           8192    /* scale for fixed point representation */
> #define from_fixed(x)   ((double) (x) / SCALE)
> 
> double x,y;
> 
>    x = (from_fixed(tpi) - utt_scale);
>    x = x / num_obser;
>    x = x + from_fixed((phead->scale));
>    y = ((from_fixed(tpi) - utt_scale)/1.0/ num_obser) + 
>      from_fixed(1.0*phead->scale);
> 
> y produces a NaN and x does not
> int num_obser = 695;
> int phead->scale = 0;
> int utt_scale = 0;
> int tpi = -924593180;
> 
> This is one of the cases that produces a NAN for y. Once y is NAN no
> matter what values tpi, and num_obser are it becomes a NaN after
> performing the calculation. 
> 
> I understand what you mean when you say the fact that it worked on FreeBsd
> and Solaris doesn't mean its correct. But I am suprised that if I use the
> linear method as in 'x', it does not occur. 
> 
> Lastly, I could not duplicate it on a smaller code. I wonder how are the
> NaN bits set on the Intel CPU. By the way is well documented that the
> Alpha chip has this problem for gcc. 

Another thing to try is explicitly setting the floating point control
word to the IEEE standard.  Some older versions of the C libraries set
the floating point control word to a non-standard value.  That can
affect the production and detection of NaN's.  Checking a recently
installed Debian 1.3 system for the file /usr/include/i386/fpu_control.h 
(included from /usr/include/fpu_control.h), it shows

 /* Linux default:
      - extended precision
      - rounding to nearest
      - exceptions on overflow, zero divide and NaN */
 #if 0
 #define _FPU_DEFAULT  0x1372 
 #else
 /* It seems SVR4/x86 uses the same thing. */
 #define _FPU_DEFAULT  0x137f 
 #endif

 /* IEEE:  same as above, but exceptions */
 #define _FPU_IEEE     0x137f

The present default behaviour is the IEEE behaviour but it used to be
different.  If you find that your libraries give a non-standard
default, either update the libraries and recompile or include that
header file in your code and call
 __setfpucw (_FPU_IEEE);
before doing any floating point calulations.  

Under the development version of Debian 2.0 the include file
/usr/include/fpu_control.h is complete by itself.  There is no
/usr/include/i386/fpu_control.h
-- 
Douglas Bates                            bates@stat.wisc.edu
Statistics Department                    608/262-2598
University of Wisconsin - Madison        http://www.stat.wisc.edu/~bates/


--
TO UNSUBSCRIBE FROM THIS MAILING LIST: e-mail the word "unsubscribe" to
debian-user-request@lists.debian.org . 
Trouble?  e-mail to templin@bucknell.edu .


Reply to: