进制 / 原反补码 / 位运算符
## 十进制转二进制
求余法:用2对数据求余,然后再对商继续求余,直到商为0结束,过程中产生的余数就是该数据的二进制(逆序)。
求权法:数据 - 2^(n-1) 如果可以减 第n位就是1,否则是0。
输入一个正整数m,显示该数据的n(>=2)进制,超过10的用字母显示。
#include <stdio.h>
int main(int argc,const char* argv[])
{
int m = 0 , n = 0;
scanf("%d%d",&m,&n);
char bits[32] = {} , cnt = 0;
while(m)
{
bits[cnt++] = m % n;
m /= n;
}
for(int i=cnt-1; i>=0; i--)
{
if(bits[i] < 10)
{
printf("%d",bits[i]);
}
else
{
printf("%c",'A'+bits[i]-10);
}
}
}
## 二进制转十进制
每位的2^(n-1) 求和 10101100 128+32+8+4 172
注意:二进制数据转换成八或十六进制是为了方便记录二进制数据。
二进制转八进制
三位二进制对应一个八进制。
例:二进制 1 010 110 010 101 100
八进制 1 2 6 2 5 4
十进制 44204
二进制转十六进制
由于计算机的发展八进制不能满足需要,因此引入十六进制来记录二进制:四位二进制对应一个十六进制。
例:二进制 1010 1100 1010 1100
十六进制 A C A C
十进制 44204
在C代码中:以0开头的是八进制数据,以0x开头的是十六进制数据。
%x 以十六进制形式显示数据
%o 以八进制形式显示数据
原码、反码、补码
补码:数据在内存存储的二进制。
正数的原码就是补码。
负数的补码:
1、绝对值转换成二进制得到原码
2、原码按位求反得到反码
3、反码+1得到补码
-127
01111111 原码
10000000 反码
10000001 补码
补码转换成数据:
无符号补码直接转换成十进制。
有符号最高位是0,说明是正数,也直接转换成十进制。
有符号且最高位是1:
1、补码-1得到反码
2、反码按位求反得到原码
3、原码转换成10进制加负号
11111111 补码 有符号
11111110 反码
00000001 原码
-1
注意:计算机中的数据都是有类型(存储空间是固定的)
位运算符:
A & B 按位相与
0101 1010 0x5A
1100 0011 0xC3
0100 0010 0x42
A | B 按位或
0101 1010 0x5A
1100 0011 0xC3
1101 1011 0xDB
~A 按位求反
0101 1010 0x5A
1010 0101 0xA5
A ^ B 按位异或
0101 1010 0x5A
1100 0011 0xC3
1001 1001 0x99
A << n 把A补码左移n位,左边的丢弃,右边补0
01011010 << 4
10100000
A >> n 把A补码右移n位,右边的丢弃,左边补符号位
11000011 >> 4
11111100
练习2:输入一个整数,把它的4~7位设置1010,其它位置不变。
n & ~(f<<4) | 0xA0
练习3:输入两个整数,把A的4~7位设置为B的3~6位,其它位置不变。
a & ~(0xf0) | (b << 1 & 0xf0)
在程序的编写中很少用到进制的转换,学习的这些东西能够更好得了解程序的运行,排除不必要的错误。