3 位最多可容纳 7 (4 + 2 + 1)。我正在尝试使用按位运算来计算它。
3 is 0b011
~3 is 0b100
做一个按位或我希望0b111(即7)。相反,我得到
int result = (~3) | 3;
printf("%i\n", result);
-1
我究竟做错了什么?
3 位最多可容纳 7 (4 + 2 + 1)。我正在尝试使用按位运算来计算它。
3 is 0b011
~3 is 0b100
做一个按位或我希望0b111(即7)。相反,我得到
int result = (~3) | 3;
printf("%i\n", result);
-1
我究竟做错了什么?
你做的一切都是正确的:N | ~N
结果是一个由全1组成的二进制表示的数字。这样的数字被解释为负数的二进制补码-1
表示。
一个 有多少位宽int
?您似乎认为它是三位宽。肯定不对!再猜。是什么~0u
?试试printf("%u\n", ~0u);
。怎么样~1u
?...和~2u
?你注意到一个模式吗?
注意u
后缀,它告诉编译器它是一个unsigned
文字。根据 n1570.pdf 的 6.2.6.2 ,您不能使用操作符处理有符号整数类型~
...好吧,您可以,但您可能会遇到陷阱表示和负零。使用陷阱表示是未定义的行为。这可能适用于您的系统,但只是巧合。你想依赖巧合吗?
同样,我建议使用该%u
指令来打印unsigned
值,因为%d
根据 n1570.pdf 的 7.21.6.1p29 会产生未定义的行为。
#include <stdio.h>
int main (){
unsigned d3 = 0b011;
unsigned invd3 = ~d3;
unsigned d4 = 0b100;
unsigned result = d3 | invd3;
printf("%X\n", result);//FFFFFFFF
result = d3 | d4;
printf("%X\n", result);//7
return 0;
}
在代码中执行此操作后
int result = (~3) | 3;
添加这一行
result= result & 0x07
这将为您提供您期望的答案。
当你这样做时,~3
你正在反转组成 3 的位 - 所以你0000 0000 0000 0000 0000 0000 0000 0011
变成1111 1111 1111 1111 1111 1111 1111 1100
. 由于设置了高位,这被解释为一个负数 - 所有的 1 都是 -1,比它少一个是 -2,少一个是 -3,依此类推。此数字是 -4 的有符号 32 位整数。
如果您将其与 3 进行二进制或,您将得到全 1(根据定义)——这是 -1 的有符号 32 位整数。
您唯一的问题是您认为您正在使用 3 位数字,但实际上您正在使用 32 位数字。