前言:
这是关于进制转化,原码,反码,补码,以及移位操作符,位操作符的题目,如果你对于某些内容不太了解,请移步:
新手入门C语言之移位操作符和位操作符-CSDN博客
一.进制之间的转化
解析:
要将二进制数 101011 转换为十进制数,可以使用权重法来计算。
二进制数的每个位上的数字可以看作是一个权重为2的幂的系数。从右到左,权重的幂逐渐增加。
对于二进制数 101011,可以按照以下计算步骤转换为十进制数:
- 从右到左,将每个位数字与相应的权重相乘: 1 * 2^0 = 1 1 * 2^1 = 2 0 * 2^2 = 0 1 * 2^3 = 8 0 * 2^4 = 0 1 * 2^5 = 32
- 将所有乘积相加: 1 + 2 + 0 + 8 + 0 + 32 = 43
因此,二进制数 101011 转换为十进制数的值为 43。
解析:
3F十六进制代表十进制为 :
16的一次方*3 + 16的零次方*F(16) = 48 + 16
即为63
解析:
- 将 5 的绝对值转换为二进制数,得到 00000101。
- 反转二进制数的每一位,得到 11111010。
- 将反转后的二进制数加 1,得到补码表示。
- 11111010 + 1 = 11111011
- 如果需要将补码表示转换回原始的负数,可以将补码再次取反,并加上负号。但在这种情况下,我们已经得到了 8 位二进制补码的表示。
因此,十进制数 -5 的 8 位二进制补码表示为 11111011。
二.原码,反码,补码
解析:
ABC正确
D关于符号位的描述说反了:0表示正数,1表示负数
三.移位操作符与位操作符
解析:
在 C 语言中,使用 ^
运算符表示按位异或(XOR)运算。按位异或运算是将两个操作数的对应位进行异或操作,如果两个对应位的值不同,则结果为 1,如果两个对应位的值相同,则结果为 0。
对于给定的表达式 x ^ y
,其中 x = 9 和 y = 3,我们可以将它们分别转换为二进制数:
x = 9 的二进制表示为 1001 y = 3 的二进制表示为 0011
因此,表达式 x ^ y
的结果是 1010,转换为十进制数为 10。
解析:
a = 12 的二进制表示为 1100 b = 5 的二进制表示为 0101
按位与运算如下所示:
1100 & 0101
0100
因此,表达式 a & b
的结果是 0100,转换为十进制数为 4。
解析:利用符号位填充,C
解析:利用0填充,A
解析:
A. & 是按位与操作符,正确
B. && 是逻辑与,不是按位与,错误
C. || 是逻辑或,错误
D. ! 是逻辑反操作符,错误
交换两个变量,不使用临时变量
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
printf("交换前:a = %d b = %d\n", a,b);
a = a^b;
b = a^b;
a = a^b;
printf("交换后:a = %d b = %d\n", a,b);
return 0;
}
统计二进制中1的个数
/*
方法一:
思路:
循环进行以下操作,直到n被缩减为0:
1. 用该数据模2,检测其是否能够被2整除
2. 可以:则该数据对应二进制比特位的最低位一定是0,否则是1,如果是1给计数加1
3. 如果n不等于0时,继续1
*/
int NumberOf1(int n)
{
int count = 0;
while(n)
{
if(n%2==1)
count++;
n = n/2;
}
return count;
}
/*
上述方法缺陷:进行了大量的取模以及除法运算,取模和除法运算的效率本来就比较低。
方法二思路:
一个int类型的数据,对应的二进制一共有32个比特位,可以采用位运算的方式一位一位的检测,具体如下
*/
int NumberOf1(unsigned int n)
{
int count = 0;
int i = 0;
for(i=0; i<32; i++)
{
if(((n>>i)&1) == 1)
count++;
}
return count;
}
/*
方法二优点:用位操作代替取模和除法运算,效率稍微比较高
缺陷:不论是什么数据,循环都要执行32次
方法三:
思路:采用相邻的两个数据进行按位与运算
举例:
9999:10 0111 0000 1111
第一次循环:n=9999 n=n&(n-1)=9999&9998= 9998
第二次循环:n=9998 n=n&(n-1)=9998&9997= 9996
第三次循环:n=9996 n=n&(n-1)=9996&9995= 9992
第四次循环:n=9992 n=n&(n-1)=9992&9991= 9984
第五次循环:n=9984 n=n&(n-1)=9984&9983= 9728
第六次循环:n=9728 n=n&(n-1)=9728&9727= 9216
第七次循环:n=9216 n=n&(n-1)=9216&9215= 8192
第八次循环:n=8192 n=n&(n-1)=8192&8191= 0
可以观察下:此种方式,数据的二进制比特位中有几个1,循环就循环几次,而且中间采用了位运算,处理起来比较高效
*/
int NumberOf1(int n)
{
int count = 0;
while(n)
{
n = n&(n-1);
count++;
}
return count;
}
打印整数二进制的奇数位和偶数位
/*
思路:
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");
}
求两个数二进制中不同位的个数
/*
思路:
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;
}