正确的方法采取INT_MIN绝对值 [英] Correct way to take absolute value of INT_MIN

查看:568
本文介绍了正确的方法采取INT_MIN绝对值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要在无符号执行一些算术和需要采取消极为int的绝对值,像

  do_some_arithmetic_in_unsigned_mode(INT some_signed_value)
{
   无符号整型幅度;
   INT阴性;
   如果(some_signed_value℃,){
       幅度= 0 - some_signed_value;
       负= 1;
    }其他{
       幅度= some_signed_value;
       负= 0;
    }
   ...略...
}

但INT_MIN可能是有问题的,0 - INT_MIN是UB如果符号算术执行。
什么是标准/强健/安全/高效的C ++做的这种方式?

编辑:

如果我们知道我们是在2补,也许隐式转换和显位OPS是标准?如果可能的话,我想避免这种假设。

  do_some_arithmetic_in_unsigned_mode(INT some_signed_value)
{
   无符号整型幅度= some_signed_value;
   诠释负= some_signed_value℃的;
   如果(负){
       幅度=(〜幅度)+ 1;
    }
   ...略...
}


解决方案

转换从符号到无符号是明确的:你得到相应的再presentative模2 N 。因此,下面会给你正确的绝对值 N

  INT N = / * ... * /;unsigned int类型abs_n = N< 0? UINT_MAX  - ((无符号整数)(N))+ 1U
                           (无符号整数)(N);

更新:的作为@ aka.nice表明,我们实际上可以替换 UINT_MAX + 1U 0 U

  unsigned int类型abs_n = N< 0: - ((无符号整数)(N)):(unsigned int类型)(N);

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...
}

解决方案

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);

这篇关于正确的方法采取INT_MIN绝对值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆