Type-independent ABS
Gabriel Maranca
gmaranca at cipc1.Dayton.NCR.COM
Thu Oct 5 23:37:26 AEST 1989
I am posting a few answers to my question on why isn't the abs function
type independent. I wish to thank everybody.
Based on the answers, my ABS macro now has become:
#define ABS(x) (((x) < 0) ? (-(x)) : (x))
If anybody decides to use it, the macro is faster and more generic than
the standard abs and labs functions, but invocations like ABS(k++) won't
work properly. A complex expression may be passed as a parameter, as long
as evaluating it three times doesn't cause problems. If the expression is
very complex, or if it is a function call, the ABS macro may wind up being
slower than the abs and labs functions.
These are the answers I got:
chris at mimsy.UUCP (Chris Torek) writes:
> >#define ABS(x) (((long)(x) < 0L)? -(x) : (x))
> The cast to long and the 0L are both unnecessary. If left out, this
> ABS will do its comparison in whatever type x has.
Thanks for illuminating me. I didn't know context type promotion was a
standard feature of C (I knew my compiler did it). This will greatly
simplify my code (I was doing these silly casts everywhere, thinking
I was creating more portable code).
> Note that ABS(k++) and the like will do `mysterious' things, and
Thanks again. This explains why abs is not a macro.
> that on most machines, ABS(largest_negative_integer) is either
> a (compile or run)-time trap or simply largest_negative_integer.
If you have time, could you explain how is this problem resolved by
the standard library function?
flaps at dgp.toronto.edu (Alan J Rosenthal) writes:
> It is portable but will only work for ints and longs. But the following
> is portable and will work for all types, including unsigned long, double,
> and long long if it exists:
> #define ABS(x) (((x) < 0) ? -(x) : (x))
> The zero will get promoted to the correct type.
Thanks. This is the same answer I got from Chris.
gwyn at brl.arpa (Doug Gwyn) writes:
> That's just the way it's always been.
English is not my native language, so I may have misinterpreted your
statement. If you mean the abs function has always been type independent,
my K&R book (second edition - pg. 253) makes reference to two functions:
int abs(int n) and long labs(long n)
But maybe you meant the abs function has always been type dependent,
which doesn't seem a very good reason for keeping it the same way.
> Note that if its argument has side effects, funny behavior may occur.
Thanks. I will avoid passing such arguments. This IS a good reason for
keeping the abs and labs functions the same.
bill davidsen (davidsen at crdos1.crd.GE.COM) writes:
> 1. instead of -(x) use (-(x)).
Good point. I had overlooked this potential trap in my original macro.
> 2. you might want to use (double) to work with more types
Per Chris and Alan, a better approach is to remove the cast altogether.
This should work with any current or future data type. Please let me
know if this is not true for some C compiler.
> 3. you still have to be careful about what you use for an
> argument to avoid things like ABS(x[m++]) which are only
> evaluated once if ABS is a procedure.
OK. I wonder how many standard library "functions" are implemented as
macros that could behave similarly? Or have such macros consistently
been avoided because of this side effect?
By the way, Bill, I am not a "she" (do not confuse Gabriel and Gabrielle) ;-)
---
#Gabriel Maranca
#Gabriel.Maranca at cipc1.Dayton.NCR.COM
#...!uunet!ncrlnk!cipc1!gmaranca
--
#Gabriel Maranca
#Gabriel.Maranca at cipc1.Dayton.NCR.COM
#...!uunet!ncrlnk!cipc1!gmaranca
More information about the Comp.lang.c
mailing list