Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!ima!haddock!karl From: karl@haddock.UUCP Newsgroups: comp.lang.c Subject: Re: fabs(x) vs. (x) < 0 ? -(x) : (x) Message-ID: <371@haddock.UUCP> Date: Sun, 8-Feb-87 16:08:04 EST Article-I.D.: haddock.371 Posted: Sun Feb 8 16:08:04 1987 Date-Received: Mon, 9-Feb-87 04:11:04 EST References: <4943@mimsy.UUCP> <2550005@hpisod2.HP> <756@unc.unc.UUCP> <2181@batcomputer.tn.cornell.edu> <1315@ho95e.ATT.COM> Reply-To: karl@haddock.ISC.COM.UUCP (Karl Heuer) Distribution: na Organization: Interactive Systems, Boston Lines: 23 Summary: bit-clear in macro won't work In article <1315@ho95e.ATT.COM> wcs@ho95e.UUCP (Bill Stewart) writes: > #define fabs(x) ( (x) & 0x7FFF ) >is probably a *lot* faster than [braner's non-floating-point] assembly >language function, since it doesn't need a function call. Dyadic "&" only applies to integral types. If you hand it a floating type, you should either get an error, or an implied cast to an integral type. A float-to-int cast is inappropriate since (altogether now) "unions take-as, but casts convert". float-pointer-to-char-pointer (as in *(char *)&x) avoids that problem, but fails if x is not an lvalue or is a register (and since the resulting expression is not an lvalue, you have the same problem trying to put the result back into a float). The "true solution" is either "#define fabs(x) __builtin_fabs(x)" (where the compiler knows how to do the bit clear for the operator __builtin_fabs), or "inline float fabs(float x) { union { int i; float f; } u; u.f=x; u.i &= BIT; return u.f; }" (where the compiler knows about "inline" and, hopefully, also optimizes out the redundant moves to/from u). Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint (For simplicity, I've ignored the distinction between float and double, and the machine-dependence which is inherent in this topic.)