我是按位操作的新手。我有AND,OR,XOR和2s补码的基本概念。但是我遇到了以下代码,我无法弄清楚输出。
char c1 = 0xFF; // -1
int shifted = c1 << 8; //-256 (-1 * 256)
printf("%d, %x\n", shifted, shifted);
int myInt;
myInt = 0xFFFFFFE2;
printf("%d\n", myInt);
int i = 0xff;
printf("%d\n", i<<2);
输出结果为:
-256,ffffff00
-30
1020
请帮助我了解这里发生了什么!
答案 0 :(得分:2)
char c1 = 0xFF; // -1
int shifted = c1 << 8; //-256 (-1 * 256)
c1
升级为int
,因此它仍为-1,转移负int
s是实现定义的,但您的实现似乎与大多数情况一样,并将其移位好像它是一个unsigned
位模式,所以左移8位乘以256。
printf( "%d, %x\n", shifted, shifted );
-256, ffffff00
正如所料。二进制补码中-256的位模式为0xFFFFFF00
(32位int
s)。
int myInt;
myInt = 0xFFFFFFE2;
该位模式在二进制补码中为-30
printf("%d\n",myInt);
int i = 0xff ;
这是255,255 * 4 = 1020
printf("%d\n", i<<2);
-30
1020
答案 1 :(得分:1)
用声明的位数写下二进制的c1,myInt和i。
将操作应用于他们。
跟进。
答案 2 :(得分:1)
好的,让我详细解释一下发生了什么。要澄清的任何二进制表示法都将以0b为前缀,左侧为最高位。
char c1 = 0xFF; // -1
char c1是一个8位有符号整数类型,设置为0b11111111
对于诸如int,short和char之类的有符号类型,最左边的位用作符号位。在two's complement中,存储有符号类型的最常用标准,任何设置了所有位的有符号整数都等于-1。
int shifted = c1 << 8; //-256 (-1 * 256)
c1在移位之前被隐式强制转换为有符号整数,因此我们的int为-1,即0xffffffff
。 C中的移位运算符是非旋转移位,即从值外“移出”的任何位将被设置为零。在班次之后,我们得到0xffffff00
,它等于-256的二进制补码。
printf( "%d, %x\n", shifted, shifted );
int myInt;
myInt = 0xFFFFFFE2;
printf("%d\n",myInt);
您正在读取一个有符号整数,该整数根据二进制补码打印。
int i = 0xff ;
printf("%d\n", i<<2);
初始i相当于0b11111111
,符号位未设置。在班次之后,我们有0b1111111100
,等于1020,这也是因为非旋转换档。希望能澄清一点事情。如果你想进行位移和AND / OR逻辑,你通常应该使用前面提到的 unsigned 类型。