正确获取INT_MIN的绝对值的方法

aka*_*ice 16 c

我想在unsigned中执行一些算术,并且需要采用负int的绝对值,类似于

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...
}
Run Code Online (Sandbox Code Playgroud)

但是INT_MIN可能有问题,0 - 如果在带符号算术中执行,INT_MIN是UB.在C中执行此操作的标准/强大/安全/有效方法是什么?

编辑:

如果我们知道我们是2补码,可能隐式转换和显式位操作是标准的吗?如果可能的话,我想避免这种假设.

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...
}
Run Code Online (Sandbox Code Playgroud)

Ker*_* SB 22

转化率从符号到无符号是明确的:你得到相应的代表模2 ñ.因此,以下将给出正确的绝对值n:

int n = /* ... */;

unsigned int abs_n = n < 0 ? UINT_MAX - ((unsigned int)(n)) + 1U
                           : (unsigned int)(n);
Run Code Online (Sandbox Code Playgroud)

更新:正如@ aka.nice建议的那样,我们实际上可以替换UINT_MAX + 1U0U:

unsigned int abs_n = n < 0 ? -((unsigned int)(n))
                           : +((unsigned int)(n));
Run Code Online (Sandbox Code Playgroud)

  • 哦,在纯粹的理论情况下,`UINT_MAX == INT_MAX == - (INT_MIN + 1)`,无论如何都不可能将`| INT_MIN |`表示为`unsigned int` =) (4认同)

R..*_*R.. 6

在否定的情况下,采取some_signed_value+1.否定它(这是安全的,因为它不可能INT_MIN).转换为无符号.然后加一个;