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使用二进制补码表示的时候.
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)
假设int是32位.
int my_abs(int x)
{
int y = (x >> 31);
return (x ^ y) - y;
}
Run Code Online (Sandbox Code Playgroud)