fabs(x) vs. (x) < 0 ? -(x) : (x)

karl at haddock.UUCP karl at haddock.UUCP
Mon Feb 9 07:08:04 AEST 1987


In article <1315 at ho95e.ATT.COM> wcs at 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 at 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.)



More information about the Comp.lang.c mailing list