Subject: Re: PERL and NetBSD 1.3_ALPHA
To: Erik Bertelsen <erik@sockdev.uni-c.dk>
From: John F. Woods <jfw@jfwhome.funhouse.com>
List: current-users
Date: 11/11/1997 10:14:46
> <       if((hx-0x3ff00000|lx)==0) return atan(y);   /* x=1.0 */
> ---
> >       if((hx-(0x3ff00000|lx))==0) return atan(y);   /* x=1.0 */

> What's lukem's (and others) opinion -- should it really be

>          if (((hx-0x3ff00000)|lx)==0) return atan(y);

I don't know about lukem's opinion, but the answer is clearly the last
version given (although I will present a better version below).

Note the comment:  "x=1.0".  hx is the high 4 bytes of the eight byte double,
lx is the low 4 bytes.  1.0 is represented as 0x3ff0000000000000 (the biased
exponent is 0x3ff).  So to determine if hx is 0x3ff00000 and lx is 0x00000000,
you can subtract 0x3ff00000 from hx, and or the result with lx.  As the code
stands now, it asks if hx is equal to 0x3ff00000 or-ed with the low word of
the float, a bizarre and silly question which accidently traps 1.2.

I would argue that better code would be

	if (hx == 0x3ff00000 && lx == 0) return atan(y); /* x=1.0 */

Yes, this will be just a bit slower on machines which punish branching.  But
it would never have gotten broken and (quickly) returned wrong answers.