I want to perform some arithmetic in unsigned, and need to take absolute value of negative int, something like
do_some_arithmetic_in_unsigned_mode(int some_signed_value)
{
unsigned int magnitude;
int negative;
if(some_signed_value<0) {
magnitude = 0 - some_signed_value;
negative = 1;
} else {
magnitude = some_signed_value;
negative = 0;
}
...snip...
}
But INT_MIN might be problematic, 0 - INT_MIN is UB if performed in signed arithmetic. What is a standard/robust/safe/efficient way to do this in C?
EDIT:
If we know we are in 2-complement, maybe implicit cast and explicit bit ops would be standard? if possible, I'd like to avoid this assumption.
do_some_arithmetic_in_unsigned_mode(int some_signed_value)
{
unsigned int magnitude=some_signed_value;
int negative=some_signed_value<0;
if (negative) {
magnitude = (~magnitude) + 1;
}
...snip...
}
These functions return the absolute value of number . Most computers use a two's complement integer representation, in which the absolute value of INT_MIN (the smallest possible int ) cannot be represented; thus, abs (INT_MIN) is not defined.
It's because there is only one zero, not a +0 and a -0 like in ones-complement.
Conversion from signed to unsigned is well-defined: You get the corresponding representative modulo 2N. Therefore, the following will give you the correct absolute value of n
:
int n = /* ... */;
unsigned int abs_n = n < 0 ? UINT_MAX - ((unsigned int)(n)) + 1U
: (unsigned int)(n);
Update: As @aka.nice suggests, we can actually replace UINT_MAX + 1U
by 0U
:
unsigned int abs_n = n < 0 ? -((unsigned int)(n))
: +((unsigned int)(n));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With