/* 在很多系统程序中常要求在位(bit)一级进行运算或处理。C语言提供了位运算的功能, 这使得C语言也能像汇编语言一样用来编写系统程序。
********************
操作符 * 作用
********************
& * 位与 1 & 1 = 1; 1 & 0 = 0; 0 & 0 = 0;
| * 位或 1 | 1 = 1; 1 | 0 = 1; 0 | 0 = 0;
^ * 位异或 1 ^ 1 = 0; 0 ^ 1 = 1; 0 ^ 0 = 0;
! * 位反 ! 1 = 0; ! 0 = 1;
>> * 右移 01011 >> 1 = 0101;
<< * 左移 01011 << 1 = 1011;
********************
按位运算是对字节或字中的实际位进行检测、设置或移位, 它只适用于字符型和整数型变量以及它们的变体, 对其它数据类型不适用。
我们要注意区分位运算和逻辑运算。
*/
//我们先来做一些练习熟悉位运算
/*由于不同位的计算机系统和编译器存储时字节数会不同,本文所有操作都在64位系统和32位编译器下执行的*/
# include<stdio.h>
void main()
{
int x; //计算整数x的二进制表示中1的个数
printf("请输入一个数\n");
scanf("%d",&x);
int count=0;
while(x)
{
count ++;
x=x & (x-1);
}
printf("%d\n",count);
********************
操作符 * 作用
********************
& * 位与 1 & 1 = 1; 1 & 0 = 0; 0 & 0 = 0;
| * 位或 1 | 1 = 1; 1 | 0 = 1; 0 | 0 = 0;
^ * 位异或 1 ^ 1 = 0; 0 ^ 1 = 1; 0 ^ 0 = 0;
! * 位反 ! 1 = 0; ! 0 = 1;
>> * 右移 01011 >> 1 = 0101;
<< * 左移 01011 << 1 = 1011;
********************
按位运算是对字节或字中的实际位进行检测、设置或移位, 它只适用于字符型和整数型变量以及它们的变体, 对其它数据类型不适用。
我们要注意区分位运算和逻辑运算。
*/
//我们先来做一些练习熟悉位运算
/*由于不同位的计算机系统和编译器存储时字节数会不同,本文所有操作都在64位系统和32位编译器下执行的*/
# include<stdio.h>
void main()
{
int x; //计算整数x的二进制表示中1的个数
printf("请输入一个数\n");
scanf("%d",&x);
int count=0;
while(x)
{
count ++;
x=x & (x-1);
}
printf("%d\n",count);
int i;
printf("输入要操作的数i\n");
scanf("%d",&i);
i = i >> 1; //去掉最后一位
i = i << 1; //往最后一位加0
i = i << 1;i=i | 1; //往最后一位加1
i = i | 1; //把最后一位变成1
i = i >> 1;i=i << 1; //把最后一位变成0
i = i ^ 1; //最后一位取反
int k;
printf("请输入k\n");
scanf("%d",&k);
i = i | (1 << (k-1)); //把右数第K位变为1
i = i & ( ~ (1 << (k-1))); //把右数第K位变为0
i = i ^ (1 << (k-1)); //把右数第k位取反
i = i & 0x00000007; //取末尾三位
i = i & (0x7fffffff >> (31-k)); //取末尾k位
i = (i >> (k-1) & 1); //取右数第k位
i = i & (i+1); //把右边连续的1变为0
i = i | (i+1); //把右边第一个0变为1
i = i | (i-1); //把右边连续的0变为1
}
//要完成上面的操做方法有很多种,这是我自己想的一些解决办法。
//下面我们就用位运算来完成float型到int型的强转。
//注:要完成此函数得先理解float型和int型的二进制存储形式。float:1个符号位、8个指数位、23个尾数位
int float_to_int(float f)
{
int *p = (int *)&f;
int temp = *p;
int sign= -1; //判断符号位
if((temp & 0x80000000) == 0)
{
sign = 1;
}
int exp = ((temp >> 23) & ox000000ff) - 127;//求出指数位
int tail = (temp & 0x007fffff) | 0x00800000;//求出尾数位
int res = tail >> (23 - exp); //求出有效数字
return sign * res; //返回整数
}
//针对上面的代码,我们对位运算有加深了印象。位运算的大体操作我们都基本作完了,掌握上面的运算就基本掌握了位运算。
printf("输入要操作的数i\n");
scanf("%d",&i);
i = i >> 1; //去掉最后一位
i = i << 1; //往最后一位加0
i = i << 1;i=i | 1; //往最后一位加1
i = i | 1; //把最后一位变成1
i = i >> 1;i=i << 1; //把最后一位变成0
i = i ^ 1; //最后一位取反
int k;
printf("请输入k\n");
scanf("%d",&k);
i = i | (1 << (k-1)); //把右数第K位变为1
i = i & ( ~ (1 << (k-1))); //把右数第K位变为0
i = i ^ (1 << (k-1)); //把右数第k位取反
i = i & 0x00000007; //取末尾三位
i = i & (0x7fffffff >> (31-k)); //取末尾k位
i = (i >> (k-1) & 1); //取右数第k位
i = i & (i+1); //把右边连续的1变为0
i = i | (i+1); //把右边第一个0变为1
i = i | (i-1); //把右边连续的0变为1
}
//要完成上面的操做方法有很多种,这是我自己想的一些解决办法。
//下面我们就用位运算来完成float型到int型的强转。
//注:要完成此函数得先理解float型和int型的二进制存储形式。float:1个符号位、8个指数位、23个尾数位
int float_to_int(float f)
{
int *p = (int *)&f;
int temp = *p;
int sign= -1; //判断符号位
if((temp & 0x80000000) == 0)
{
sign = 1;
}
int exp = ((temp >> 23) & ox000000ff) - 127;//求出指数位
int tail = (temp & 0x007fffff) | 0x00800000;//求出尾数位
int res = tail >> (23 - exp); //求出有效数字
return sign * res; //返回整数
}
//针对上面的代码,我们对位运算有加深了印象。位运算的大体操作我们都基本作完了,掌握上面的运算就基本掌握了位运算。