我不完全理解如何“ - ”操作会影响下面的代码:
#define COMP(x) ((x) & -(x))
unsigned short a = 0xA55A;
unsigned short b = 0x0400;
有人能解释什么COMP(a)和COMP(b)的以及它们是如何计算出来的?
在“ - ”在two's complement方式签署短参数为负的值。 (简言之,把所有0至1,1到0,然后添加1)
所以0xA55A二进制是1010 0101 0101 1010
然后 - (0xA55A)以二进制为0101 1010 1010 0110
运行&
他们之间将会给你0000 0000 0000 0010
(x) & -(x)
使用2的补数来表示二进制数时,等于在x
最低位集。
这意味着COMP(a) == 0x0002;
和COMP(b) == 0x0400;
-(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)
}
当你BITAND与其bitfliped值的值,则得到0。如果其值bitfliped + 1(=其取反值)你从右侧得到的第一个非零比特BITAND的值。
为什么?如果~x
的最右边的位是1时,将1加到它会产生与0
carry=1
。重复此而最右边位是1,零这些位。一旦你打零(这将是1
在x
,因为你加1 ~x
),它就会变成1进== 0,所以除结束。在右边你有零,你有bitflips左侧。您BITAND这与原来和你从右边的第一个非零位。
基本上,COMP确实是和两个操作数,其中一个是在其原来的形式和其中一个是它的一个否定的形式。
如何的CPU通常处理符号数是使用2's Complement,2的补码分割数字数据类型的范围内为2,其中(2 ^ N-1)-1为正和(2 ^ N-1)是负的。
该MSB(最右位)表示的数字数据的符号
EG
0111 -> +7
0110 -> +6
0000 -> +0
1111 -> -1
1110 -> -2
1100 -> -6
那么,什么COMP确实通过对数字数据的正面和负面的版本做的,并且是获得LSB(最左边位)第1。
我写了一些示例代码,可以帮助你了解这里:http://coliru.stacked-crooked.com/a/935c3452b31ba76c