Tim Rentsch said:
unsigned
unsigned_abs( int n ){
return n >= 0 ? n : -(n+1) + 1UL;
}
Note that for implementations where UINT_MAX == INT_MAX,
and where INT_MIN == -INT_MAX - 1 (which must be two's
complement), there is no unsigned int value that's right.
Under these conditions, unsigned_abs( INT_MIN ) gives zero.
In all other cases it gives the right value.
I was asking because some implementations of >>itoa<< start
with something like:
if( n < 0 ){ n = -n; *p++ = '-'; }
, but then seem to fail sometimes for INT_MIN.
I was wondering whether there is a portable implementation
that will be correct for all int values. [snip]
void
simple_itoa( int n, char *s ){
enum { D = 1 + CHAR_BIT*sizeof(int)/3 };
char buffer[D+1], *p = buffer + D;
*p = 0;
if( n < 0 ) *s++ = '-';
if( n > 0 ) n = -n;
while( n < -9 ){
int r = -(n+10)%10;
*--p = '0' + r;
n = (n+r)/10;
}
*--p = '0' + -n;
strcpy( s, p );
}
1. Works for all int values.
2. No casting or other types needed (and so no dependencies
on ranges of any other types).
3. No checks for "unusual" values.
4. Same results under both C90 and C99 (and C11) semantics.
5. (The expression computing a value for 'D' can be
improved, but the one here is probably good enough
in most cases.)
The code above may be used freely for any purpose subject
only to the condition that it not be claimed as original
work, ie, by anyone other than me. (And especially not
by any patent trolls out there...)