正确的方法采取INT_MIN绝对值 [英] Correct way to take absolute value of 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屋!