如何计算整数绝对值

Pra*_*yan 27 algorithm bit-manipulation

如何在不使用if条件的情况下计算整数绝对值.我想我们需要使用一些按位操作.有人可以帮忙吗?

Chr*_*ica 76

与现有答案相同,但有更多解释:

让我们假设一个二进制补码数(因为它是通常的情况,你没有另外说),让我们假设32位:

首先,我们执行算术右移31位.这会将所有1s转换为负数或全部转换0为正数(但请注意,实际操作>>符在C或C++中的行为是为负数定义的实现,但通常也会执行算术移位,但我们只假设伪代码或实际的硬件指令,因为它听起来像家庭作业):

mask = x >> 31;
Run Code Online (Sandbox Code Playgroud)

所以我们得到的是111...111负数(-1)和正数000...000(0)

现在我们对此进行异或x,得到mask=111...111(负)的NOT行为和(正)的无行为mask=000...000:

x = x XOR mask;
Run Code Online (Sandbox Code Playgroud)

最后减去我们的掩码,这意味着+1为负数,+ 0/no-op为正数:

x = x - mask;
Run Code Online (Sandbox Code Playgroud)

因此,对于正数,我们执行XOR为0且减法为0,从而获得相同的数字.对于否定,我们得到了(NOT x) + 1,这正是-x使用二进制补码表示的时候.

  • Upvote的清晰解释,比接受的答案要好得多! (4认同)

Mad*_*ady 27

1)将掩码设置为整数右移31(假设整数存储为二进制补码32位值,并且右移运算符执行符号扩展).

 mask = n>>31 
Run Code Online (Sandbox Code Playgroud)

2)用数字对掩模进行异或

mask ^ n 
Run Code Online (Sandbox Code Playgroud)

3)从步骤2的结果中减去掩码并返回结果.

(mask^n) - mask 
Run Code Online (Sandbox Code Playgroud)


tim*_*rau 6

假设int是32位.

int my_abs(int x)
{
    int y = (x >> 31);
    return (x ^ y) - y;
}
Run Code Online (Sandbox Code Playgroud)