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