C语言,详解二进制位运算
来源:华佗健康网
前言
最近对于二进制的运算挺感兴趣的,在查阅诸多资料,并且自己写了demo后,对于位运算也有了一定的了解,在此记录本次的学习
一、位运算
数据在计算机内部是使用二进制数来储存的,因此使用位运算可以加快程序运行的效率
这些整数是使用补码来储存的,例如
正数 3 原码 0011 反码 0011 补码 0011
负数 -3 原码 1011 反码 1100 补码 1101
二、取反
三、运算
四、函数操作
1、两数交换
当然了,当前的交换只在函数内有效,如果想实现真正的交换,需要加上指针操作
2、改变符号
如图所示,取反再加一,即可改变符号
3、取绝对值
对于正数,绝对值就是他本身
对于负数,绝对值就是取反再加一
4、判断奇偶性
个人感觉这种判断方法更方便
5、求模
15 % 4 = 3
6、两数相加
两数相加的流程就有些麻烦了
五、总结
#include <stdio.h>
void swap(int a, int b);//两数交换数值
void change_sign(int a);//改变符号
void num_abs(int a);//求绝对值
int main(){
// 运算时,都是根据补码进行运算的,正数补码与原码一样,而负数则是符号位不变,其余取反,末位加一
// 取反运算:~
// 15 原码:0000 1111 补码:0000 1111 ~15 --> 补码:1111 0000 --> 原码:1001 0000 --> -16
//-15 原码:1000 1111 补码:1111 0001 ~-15 --> 补码:0000 1110 --> 原码:0000 1110 --> 14
int a = 15, b = 16;
int res = ~a;
// ******************************************************************************
// 与运算 & ,15 & 0 --> 0000 1111 & 0000 0000 = 0000 0000 即为 0
// 或运算 | ,15 | 0 --> 0000 1111 | 0000 0000 = 0000 1111 即为自己本身
// 异或运算 ^ 15 ^ -2 --> 0000 1111 ^ 1000 0010 == 0000 1111 ^ 1111 1111 = 1111 0000 --> 1000 1111 = -15
// -15 ^ 2 --> 1000 1111 ^ 0000 0010 == 1111 0001 ^ 0000 0010 = 1111 0011 --> 1000 1101 即为 -13
res = a ^ 2;
printf("异或: a ^ 2 = %d \n\n", res);
// ******************************************************************************
// 左移 15 << k 二进制码全部向左移动 k 个,右边补 0 0000 1111 << 1 --> 0001 1110 即为 30
// 左移 -15 << k 1111 0001 << 1 --> 1110 0010 --> 1001 1110 即为 -30
// 右移 15 >> k 二进制码全部向右移动 k 个,左边补 0 0000 1111 >> 1 --> 0000 0111 即为 7
// 右移 -15 >> k 1111 0001 >> 1 --> 1111 1000 --> 1000 1000 即为 -8
// 负数左边补 1,右边补 0
res = a << 1;
printf("左移: a << 1 = %d \n\n", res);
// ******************************************************************************
// 任何数 << 1 === * 2
// 对于偶数来说 >> 1 === / 2
// 16 << 1 0001 0000 --> 0010 1000 即为 32
// 16 >> 1 0001 0000 --> 0000 1000 即为 8
// 对于奇数,则在最后结果上加上0.5
// 13 >> 1 0000 1101 --> 0000 0110 即为 6
// 15 >> 1 0000 1111 --> 0000 0111 即为 7
// 17 >> 1 0001 0001 --> 0000 1000 即为 8
res = 15 >> 1;
printf("右移: 15 >> 1 = %f \n\n", res + 0.5);
// ******************************************************************************
// 两数交换 1, 2
// a = 1 ^ 2 --> 0000 0001 ^ 0000 0010 = 0000 0011 = 3
// b = 2 ^ 3 --> 0000 0010 ^ 0000 0011 = 0000 0001 = 1
// a = 3 ^ 1 --> 0000 0011 ^ 0000 0001 = 0000 0010 = 2
// 交换完之后即为 2, 1
swap(1, 2);
// ******************************************************************************
// 改变符号 -2
// ~-2 + 1 --> 1000 0010 --> 1111 1110 --> 0000 0010 即为 2
// ~2 + 1 --> 0000 0010 --> 1111 1110 --> 1000 0010 即为 -2
change_sign(-2);
// ******************************************************************************
// 求绝对值
// 正数便返回正数
num_abs(-2);
// ******************************************************************************
// 判断奇偶性 与 1 相与
// 5 & 1 --> 0000 0101 & 0000 0001 = 0000 0001 = 1 奇数
// 6 & 1 --> 0000 0110 & 0000 0001 = 0000 0000 = 0 偶数
if (a & 1)
printf("奇数\n\n");
else
printf("偶数\n\n");
// ******************************************************************************
// 求模 但是得是 2的k次方
// 15 & (4 - 1) --> 0000 1111 & 0000 0011 = 0000 0011 = 3 即为 15 % 4 = 3
printf("求模: a & (4 - 1) = %d \n\n", a & (4 - 1));
// ******************************************************************************
a = 13;
b = 7;
// 两数相加 13 + 7
// 0000 1101 ^ 0000 0111 = 0000 1010 = 10
// 0000 1101 & 0000 0111 = 0000 0101 << 1 --> 0000 1010 = 10
// a = 10 b = 10
// 0000 1010 ^ 0000 1010 = 0000 0000 = 0
// 0000 1010 & 0000 1010 = 0000 1010 << 1 --> 0001 0100 = 20
// a = 0 b = 20
// 0000 0000 ^ 0001 0100 = 0001 0100 = 20
// 0000 0000 & 0001 0100 = 0000 0000 << 1 --> 0000 0000 = 0
// a = 20 b = 0
// 循环结束,最后结果为 20
while(b){
int temp_a = a ^ b;
int temp_b = (a & b) << 1;
a = temp_a;
b = temp_b;
}
printf("相加: 13 + 7 = %d\n\n", a);
return 0;
}
void swap(int a, int b){
printf("交换前: a = %d, b = %d\n", a, b);
a ^= b;
b ^= a;
a ^= b;
printf("交换后: a = %d, b = %d\n\n", a, b);
}
void change_sign(int a){
printf("改变前的值: %d\n", a);
printf("改变后的值: %d\n\n", ~a + 1);
}
void num_abs(int a){
printf("求绝对值前的值: %d\n", a);
// -2 >> 31 得到的是 -1
// 负数右移,在左边补1,之后转成原码,即为 -1
printf("求绝对值后的值: %d\n\n", a ^ (a >> 31) ? a : ~ a + 1);
}
以上就是本人整理的有关C语言位运算的操作了,希望对大家有帮助
因篇幅问题不能全部显示,请点此查看更多更全内容