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: