3位最多可以容纳7(4 + 2 + 1)。我正在尝试使用按位运算来计算它。
3 is 0b011
~3 is 0b100
按位进行或我希望0b111(即7)。相反,我得到
int result = (~3) | 3;
printf("%i\n", result);
-1
我做错了什么?
答案 0 :(得分:6)
您正在做的一切正确:N | ~N
会产生一个二进制表示的数字,包含所有数字。这个数字在two's compliment中以负数表示为-1
。
答案 1 :(得分:4)
int
的宽度是多少?你似乎认为它有三位宽。当然不正确!再猜。什么是~0u
?试试printf("%u\n", ~0u);
。那么~1u
呢? ......和~2u
?你注意到一种模式吗?
请注意u
后缀,它告诉编译器它是unsigned
字面值。您无法使用带有~
运算符的有符号整数类型...嗯,您可以,但根据n1570的6.2.6.2,您可能遇到陷阱表示和负零。 .PDF。使用陷阱表示是未定义的行为。 可能在您的系统上工作,但只是巧合。你想依靠巧合吗?
同样,我建议使用%u
指令来打印unsigned
值,因为%d
会根据n1570.pdf的7.21.6.1p29产生未定义的行为。
答案 2 :(得分:0)
当您执行~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位数字。
答案 3 :(得分:0)
在代码中执行此操作后
int result = (~3) | 3;
添加此行
result= result & 0x07
这将为您提供您期望的答案。
答案 4 :(得分:0)
#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;
}