我不完全了解“-”运算符如何影响以下代码:
#define COMP(x) ((x) & -(x))
unsigned short a = 0xA55A;
unsigned short b = 0x0400;
有人可以解释一下COMP(a)和COMP(b)以及它们的计算方式吗?
答案 0 :(得分:6)
(x) & -(x)
等于使用2的补数表示二进制数时在x
中设置的最低位。
这意味着COMP(a) == 0x0002;
和COMP(b) == 0x0400;
答案 1 :(得分:4)
“-”号以two's complement的方式使short参数的值负。 (简而言之,将所有0变成1,从1变成0,然后再加1)
所以二进制的0xA55A是1010 0101 0101 1010
那么-(0xA55A)二进制为0101 1010 1010 0110
在它们之间运行&
会给您0000 0000 0000 0010
答案 2 :(得分:0)
-(x)
取反x
。二进制补码的负数与~x+1
(bitflip + 1)相同
如下代码所示:
#include <stdio.h>
#include <stdio.h>
#include <stdint.h>
int prbits(uintmax_t X, int N /*how many bits to print (from the low end)*/)
{
int n=0;
uintmax_t shift=(uintmax_t)1<<(N-1);
for(;shift;n++,shift>>=1) putchar( (X&shift)?'1':'0');
return n;
}
int main()
{
prbits(0xA55A,16),puts("");
//1010010101011010
prbits(~0xA55A,16),puts("");
//0101101010100101
prbits(~0xA55A+1,16),puts("");
//0101101010100110
prbits(-0xA55A,16),puts("");
//0101101010100110 (same)
}
用位翻转的值对值进行位取值时,得到0。用位翻转的值+ 1(取其负值)值取值时,从右边得到第一个非零位。
为什么?如果~x
的最右位为1,则向其加1将产生0
和carry=1
。您在最右边的位为1并将这些位清零时重复此操作。一旦您达到零(在1
中将为x
,因为您要向~x
加1),它将变为1,进位== 0,因此加法结束。右边有零,左边有位翻转。您将其与原始位进行咬合,然后从右侧获得第一个非零位。
答案 3 :(得分:0)
基本上,COMP的作用是AND,两个操作数是其原始形式,而其中一个是其形式的否定。
CPU通常如何使用2's Complement处理带符号的数字,2的补码将数字数据类型的范围拆分为2,其中(2 ^ n-1)-1为正,(2 ^ n-1 )为负。
MSB(最右边的位)代表数字数据的符号
例如
0111 -> +7
0110 -> +6
0000 -> +0
1111 -> -1
1110 -> -2
1100 -> -6
因此,COMP通过对数字数据的正负版本进行“与”运算来获得第一个1的LSB(最左位)。
我写了一些示例代码,可以帮助您在这里理解: http://coliru.stacked-crooked.com/a/935c3452b31ba76c