1.原码,反码,补码
正整数的原码,反码,补码都相同。
负数的反码补码需要计算求出
负数的反码是符号位不变,其它的取反
补码是在反码的基础上加1
最高位表示符号位,如果是0是正数,如果是1是负数
整数在内存中存储的是补码的二进制
//5
//
// 原码:00000000000000000000000000000101
// 反码:00000000000000000000000000000101
// 补码:00000000000000000000000000000101
/* -5*/
// 原码:10000000000000000000000000000101
// 反码:11111111111111111111111111111010
// 补码:11111111111111111111111111111011
补码求原码也可以符号位不变,其它的取反,然后再加1
2.位操作符
![](https://img-blog.csdnimg.cn/daa198241bd24dbb9fc76385e27d0055.png)
按位与& ,两个都是1才为1,有一个0就是0
按位或|,两个都是0才为0,有一个1就是1
按位^,相同为0,相异为1
这个性质有个小结论 (a^a=0) (a^0=a)
逻辑与 &&,两边都是非0的,就是真,结果为1,有一个为0的,就是假,结果为0
逻辑或 ||,两边都是0才为假,有一个为真的结果为真结果为1
&&逻辑与 ,左边为假,右边就不计算了,肯定为假
| | 逻辑或,左边为真,右边就不计算了,肯定为真
~ 对一个数的二进制按位取反, 所有位包括符号位
3.整形提升
整形提升是按照变量的数据类型的符号位来提升的
用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转 换为int或unsigned int,然后才能送入CPU去执行运算。
int main()
{
char a = 3;
//00000000000000000000000000000011 原码
//00000000000000000000000000000011 反码
//00000000000000000000000000000011 补码
//
//char类型占1个字节,变量c1的二进制位(补码)中只有8个比特位:后8位
// 00000011 进行整形提升,高位补充符号位,即为0,0就是符号位
//00000000000000000000000000000011 补
char b = 127;
//00000000000000000000000001111111 原码
//00000000000000000000000001111111 反码
//00000000000000000000000001111111 补码
//01111111 进行整形提升,高位补充符号位,即为0,此时0就是符号位
//00000000000000000000000001111111 补码
// 00000000000000000000000000000011 相加
// 00000000000000000000000001111111
// 00000000000000000000000010000010
// char c3放的10000010
//对c3进行整形提升,高位补充符号位,即为1,此时1就是符号位
//11111111111111111111111110000010 补码
//10000000000000000000000001111101
//10000000000000000000000001111110 要打印原码 -126
(整形提升的时候,高位补充符号位) 整形提升出来的是补码,打印的话转化成原码
(小于int类型的都要先提升成int然后进行计算)
4.sizeof(-1)
sizeof的返回值类型实际为无符号整形,因此编译器会自动将左侧i自动转换为无符号整形的数据\
-1对应的无符号整形是一个非常大的数字,超过4或者8.
5.计算一个数中二进制1的个数
计算一个二进制的数是可以用按位&1,这样可以把最后一位进行比较或者试试.
1是00000000000000000000000000000001.
int pubb(int n)
{
int i = 0;
int count = 0;
for (i = 0; i < 32; i++)
{
if ((n >> i) & 1 == 1)
{
count++;
}
}
return count;
}
int main()
{
int num = 0;
scanf("%d", &num);
int n = pubb(num);
printf("%d\n", n);
return 0;
}
还有一种巧妙的办法,不容易想到,利用下面,可以把给消去,我们可以写成
int count =0;
while(n)
{
n=n&(n-1); 这里n一直循环,直到全为0,就停下来,记录几次
count++;
}