一,概念
加法
乘法
减法
除法
二,二进制,十进制,十六进制转化
二进制转十进制
十进制转二进制
二进制转十六进制
十六进制转二进制
三,原码,反码,补码
正数
负数
四,操作符中的运用
<< 左移操作符
>> 右移操作符
五,位操作符
&按位与
|按位或
^按位异或
六,笔试题
1,求两个数二进制中不同位的个数
2,打印整数二进制的奇数位和偶数位
3,统计二进制中1的个数
一,概念
二进制(binary)是在数学和数字电路中指以2为基数的记数系统,是以2为基数代表系统的二进位制。这一系统中,通常用两个不同的符号0(代表零)和1(代表一)来表示 。
数字电子电路中,逻辑门的实现直接应用了二进制,因此现代的计算机和依赖计算机的设备里都用到二进制。每个数字称为一个比特(Bit,Binary digit的缩写)。
加法
二进制加法有四种情况: 0+0=0,0+1=1,1+0=1,1+1=10(0 进位为1)
乘法
二进制乘法有四种情况: 0×0=0,1×0=0,0×1=0,1×1=1
减法
二进制减法有四种情况:0-0=0,1-0=1,1-1=0,0-1=1
除法
二进制除法有两种情况(除数只能为1):0÷1=0,1÷1=1
二,二进制,十进制,十六进制转化
二进制转十进制
方法:“按权展开求和”,该方法的具体步骤是先将二进制的数写成加权系数展开式,而后根据十进制的加法规则进行求和
规律:个位上的数字的次数是0,十位上的数字的次数是1,......,依次递增,而十分位的数字的次数是-1,百分位上数字的次数是-2,......,依次递减。
十进制转二进制
一个十进制数转换为二进制数要分整数部分和小数部分分别转换,最后再组合到一起。
整数部分采用 "除2取余,逆序排列"法。具体做法是:用2整除十进制整数,可以得到一个商和余数;再用2去除商,又会得到一个商和余数,如此进行,直到商为小于1时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。
例:125
小数部分要使用“乘 2 取整法”。即用十进制的小数乘以 2 并取走结果的整数(必是 0 或 1),然后再用剩下的小数重复刚才的步骤,直到剩余的小数为 0 时停止,最后将每次得到的整数部分按先后顺序从左到右排列即得到所对应二进制小数。例如,将十进制小数 0.8125 转换成二进制小数过程如下。
当然最快速的方法是记得2所有次方对应的值
0 1 2 4 8 16 32 64 128
0.5 0.25 0.125 0.625
通过比较相应位次的大小累加得到目标值,学过网络技术的理解最深刻。
二进制转十六进制
二进制 | 十六进制 |
0000 | 0 |
0001 | 1 |
0010 | 2 |
0011 | 3 |
0100 | 4 |
0101 | 5 |
0110 | 6 |
0111 | 7 |
1000 | 8 |
1001 | 9 |
1010 | A |
1011 | B |
1100 | C |
1101 | D |
1110 | E |
1111 | F |
二进制转16进制,取四位 合一位,从小数点开始,向左向右取,到高位,不够位数 补0,16进制的表示法,用字母H后缀表示,比如BH就表示16进制数11;也可以用0X前缀表示,比如0X23就是16进制的23.
十六进制转二进制
例:CF6.53
C:1100 F: 1111 6:0110 5:0101 3:0011
所以对应二进制:1100 1111 0110.0101 0011
三,原码,反码,补码
正数:
原码、反码、补码相同;
以123为例:
原码:01111011
反码:01111011
补码:01111011
负数
负数的原码:为取绝对值的数转二进制,然后符号位加一;
负数的反码:对该数的原码除符号位外,各位取反;
负数的补码:对该数的反码加1。负数的补码即为负数的二进制数。
以-123为例:
原码:11111011,其中最高位1为符号位。
反码:10000100
补码:10000101
四,操作符中的运用
位移操作符
<< 左移操作符
#include<stdio.h>
int main()
{
int num = 10;
int b = 10 << 1;
printf("%d", b);
return 0;
}
左移操作符 移位规则
左边抛弃、右边补0
int main()
{
int a = 5;//4byte = 32bit
int b = a << 1;
//int b = a + 1;
printf("%d\n", b);
printf("%d\n", a);
//00000000000000000000000000000101
//00000000000000000000000000000101
//00000000000000000000000000000101
}
>> 右移操作符
#include<stdio.h>
int main()
{
int a = -1;
int b = -1 >> 1;
printf("%d", b);
return 0;
}
右移操作符 移位规则:
1. 逻辑移位 左边用0填充,右边丢弃
2. 算术移位 左边用原该值的符号位填充,右边丢弃
int main()
{
int a = -1;
int b = -1 >> 1;
printf("%d", b);
return 0;
// 11111111111111111111
// 算数右移 11111111111111111111
// 逻辑右移 01111111111111111111
}
int main()
{
int c = -1;
int d = c << 1;
printf("%d\n", d);//打印的是原码的值
//10000000000000000000000000000001 - 原码
//11111111111111111111111111111110 - 反码
//11111111111111111111111111111111 - 补码
return 0;
}
对于移位运算符,不要移动负数位,这个是标准未定义的。 例如:
int num = 10;
num>>-1;//error
五,位操作符
& | ^ | //按位与 //按位或 //按位异或 |
&按位与
int main()
{
int a = 3;
int b = -2;
int c = a & b;
printf("%d\n", c);
//%d - 说明我们要打印c的值,以有符号的形式
return 0;
}
//10000000000000000000000000000010 -2的原码
//11111111111111111111111111111101 -2的反码
//11111111111111111111111111111110 -2的补码
//00000000000000000000000000000011 3的补码
//00000000000000000000000000000011
//11111111111111111111111111111110
//00000000000000000000000000000010
结果为2
|按位或
int main()
{
int a = 3;
int b = -2;
int c = a | b;
printf("%d\n", c);
return 0;
}
//10000000000000000000000000000010 -2的原码
//11111111111111111111111111111101 -2的反码
//11111111111111111111111111111110 -2的补码
//00000000000000000000000000000011 3的补码
//11111111111111111111111111111110
//00000000000000000000000000000011
//11111111111111111111111111111111
结果为-1
^按位异或
int main()
{
int a = 3;
int b = -2;
int c = a ^ b;
printf("%d\n", c);
//%d - 说明我们要打印c的值,以有符号的形式
return 0;
}
//10000000000000000000000000000010 -2的原码
//11111111111111111111111111111101 -2的反码
//11111111111111111111111111111110 -2的补码
//00000000000000000000000000000011 3的补码
//异或 - 相同为0,相异为1
//11111111111111111111111111111110
//00000000000000000000000000000011
//11111111111111111111111111111101
结果为-3
六,笔试题
1,求两个数二进制中不同位的个数
1. 先将m和n进行按位异或,此时m和n相同的二进制比特位清零,不同的二进制比特位为1
2. 统计异或完成后结果的二进制比特位中有多少个1即可
#include <stdio.h>
int calc_diff_bit(int m, int n)
{
int tmp = m^n;
int count = 0;
while(tmp)
{
tmp = tmp&(tmp-1);
count++;
}
return count;
}
int main()
{
int m,n;
while(scanf("%d %d", &m, &n) == 2)
{
printf("%d\n", calc_diff_bit(m, n));
}
return 0;
}
2,打印整数二进制的奇数位和偶数位
1. 提取所有的奇数位,如果该位是1,输出1,是0则输出0
2. 以同样的方式提取偶数位置
检测num中某一位是0还是1的方式:
1. 将num向右移动i位
2. 将移完位之后的结果与1按位与,如果:
结果是0,则第i个比特位是0
结果是非0,则第i个比特位是1
void Printbit(int num)
{
for(int i=31; i>=1; i-=2)
{
printf("%d ", (num>>i)&1);
}
printf("\n");
for(int i=30; i>=0; i-=2)
{
printf("%d ", (num>>i)&1);
}
printf("\n");
}
3,统计二进制中1的个数
方法一:
int count_one_bit(int n)
{
int count = 0;
while(n)
{
if(n%2==1)
count++;
n = n/2;
}
return count;
}
方法二:
int count_one_bit(unsigned int n)
{
int count = 0;
int i = 0;
for(i=0; i<32; i++)
{
if(((n>>i)&1) == 1)
count++;
}
return count;
}
方法三:
int count_one_bit(int n)
{
int count = 0;
while(n)
{
n = n&(n-1);
count++;
}
return count;
}