一、原码反码补码的转换
①对于正数而言,它的原码=反码=补码
eg:
以8bit的数据存储为例讲解。
+10 原码:00001010反码:00001010补码:00001010
在内存中以补码存储
②对于负数而言
负数的反码:符号位不变,对原码其它位依次取反。0变1,1变0
负数的补码:符号位不变,反码+1
eg:
-10 原码:10001010反码:11110101补码:11110110
在内存中以补码存储
补码转换为原码
- 方法1:原码=补码-1,然后符号位不变,按位取反
- 方法2:对补码再求一次补码=原码(推荐)
二、位运算
1、位运算符
运符算 | 格式 | 功能 | 结果 |
---|---|---|---|
& | 表达式1&表达式2 | 按位与 | 1按位与1结果是1,1按位与0结果是0,0按位与0结果是0 |
| | 表达式1|表达式2 | 按位或 | 1按位或0结果是1,1按位或1结果是1,0按位或0结果是0 |
^ | 表达式1^表达式2 | 按位异或 | 相同为0,不同为1 |
~ | 表达式1~表达式2 | 按位取反 | 1变成0,0变成1 |
<< | 表达式<<左移位数 | 左移 | 无论是正数还是负数,左移都是对应的二进制位向左移动高位丢弃,低位补0左移的时候,等价于将这个数据乘以2 |
>> | 表达式>>右移位数 | 右移 | 右移,向右移动,低位丢弃,高位正数补0,负数补1 |
eg:-3左移3位
-3 的原码:1000 0011 补码:1111 1101
补码左移三位 : 1110 1000原码:1001 1000(二进制转十进制)-(8+16)=-24
-24右移6位
-24 的原码1001 1000补码:1110 1000
补码右移6位,高位补11111 1111原码:1000 0001十进制:-1
#include <stdio.h>
int main(){unsigned char reg = 3; char a = -3; reg = reg << 3; printf("reg = %d\n",reg);a = a << 3; printf("a = %d\n",a); a = a >> 6; printf("a = %d\n",a); return 0;
}
运算结果:
reg = 24
a = -24
a = -1
一个异或的技巧:
不借助第三方变量,交换a和b的值
#include <stdio.h>
int main(){
unsigned char a = 10,b = 15;
unsigned char t = 0;printf("a = %d b = %d\n",a,b); a = a ^ b;b = a ^ b; //(a^b)^b=a (b^b=0 0^a=a )a = a ^ b;printf("a = %d b = %d\n",a,b); return 0;}