C语言,详解二进制位运算
本文章主要讲解整数的位运算,供大家参考
文章目录
前言
一、位运算
二、取反
三、运算
四、函数操作
1、两数交换
2、改变符号
3、取绝对值
4、判断奇偶性
5、求模
6、两数相加
五、总结
前言
最近对于二进制的运算挺感兴趣的,在查阅诸多资料,并且自己写了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 --> 14int 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 即为 -13res = 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,右边补 0res = 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 即为 8res = 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, 1swap(1, 2);// ******************************************************************************// 改变符号 -2// ~-2 + 1 --> 1000 0010 --> 1111 1110 --> 0000 0010 即为 2 // ~2 + 1 --> 0000 0010 --> 1111 1110 --> 1000 0010 即为 -2change_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");elseprintf("偶数\n\n");// ******************************************************************************// 求模 但是得是 2的k次方// 15 & (4 - 1) --> 0000 1111 & 0000 0011 = 0000 0011 = 3 即为 15 % 4 = 3printf("求模: 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// 循环结束,最后结果为 20while(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,之后转成原码,即为 -1printf("求绝对值后的值: %d\n\n", a ^ (a >> 31) ? a : ~ a + 1);
}
以上就是本人整理的有关C语言位运算的操作了,希望对大家有帮助
C语言,详解二进制位运算相关推荐
- c语言霍夫曼函数,使用C语言详解霍夫曼树数据结构
1.基本概念 a.路径和路径长度 若在一棵树中存在着一个结点序列 k1,k2,--,kj, 使得 ki是ki+1 的双亲(1<=i 从 k1 到 kj 所经过的分支数称为这两点之间的路径长度,它 ...
- Drools 规则语言详解(上)
http://www.blogjava.net/guangnian0412/archive/2006/06/09/51574.html http://www.blogjava.net/guangnia ...
- 克鲁斯卡尔算法c语言,Kruskal算法(一)之 C语言详解
最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树. 例如,对于如上图G4所示的连通网可以有多棵权值总和 ...
- c++指针详解_c语言详解sizeof
一.sizeof的概念 sizeof是C语言的一种单目操作符,如C语言的其他操作符++.--等. 它并不是函数. sizeof操作符以字节形式给出了其操作数的存储大小. 操作数可以是一个表达式或括在括 ...
- 排座系统c语言,2008noip排座位C语言详解.doc
2008noip排座位C语言详解 2008noip排座位C语言详解 2.排座椅 (seat.pas/c/cpp)D对同学上课时会交头接耳.同学们在教室中坐成了M行N列,坐在第i行第j列 的同学的位置是 ...
- 有向图邻接矩阵c语言编程,邻接矩阵有向图(一)之 C语言详解
本章介绍邻接矩阵有向图.在"图的理论基础"中已经对图进行了理论介绍,这里就不再对图的概念进行重复说明了.和以往一样,本文会先给出C语言的实现:后续再分别给出C++和Java版本的实 ...
- 邻接矩阵用c语言,邻接矩阵无向图(一)之 C语言详解
本章介绍邻接矩阵无向图.在"图的理论基础"中已经对图进行了理论介绍,这里就不再对图的概念进行重复说明了.和以往一样,本文会先给出C语言的实现:后续再分别给出C++和Java版本的实 ...
- 如何用c语言编写stm32的程序吗,STM32入门C语言详解
<STM32入门C语言详解>由会员分享,可在线阅读,更多相关<STM32入门C语言详解(6页珍藏版)>请在人人文库网上搜索. 1.最新 料推荐阅读 flash : 芯片内部存储 ...
- 顺序栈基本操作(入栈和出栈)C语言详解
#include <stdio.h> #include <stdlib.h> /*顺序栈基本操作(入栈和出栈)C语言详解栈的具体实现(1)顺序栈(2)链栈栈的应用(1)回退 ( ...
最新文章
- mysql 带宽字段_技术分享 | 网络带宽如何影响 MySQL 性能
- 51nod1238 最小公倍数之和 V3
- python3 字符串查找 效率比较
- mysql远程连接oracle数据库服务器配置_远程访问oracle数据库
- shell date
- obj[]与obj._Ruby中带有示例的Array.rassoc(obj)方法
- 吴恩达机器学习笔记二之多变量线性回归
- 全球芯片供应不足!苹果iPhone生产可能面临中断风险
- 固态硬盘ps3111开卡工具_固态硬盘必备工具:系统无损迁移、僵尸文件立现原形...
- 如何用 Python 写 Excel 中 Vlookup 函数?
- 一文解读聚类中的两种流行算法
- Vmware虚拟机linux系统混合模式上网
- html+link+点击次数,使用正则表达式,取得点击次数,函数抽离(示例代码)
- 基于selenium的python浏览器脚本制作教程
- 计算机白板培训心得,电子白板培训心得体会
- 【文献心得】内存隔离技术研究现状调研
- 斗鱼直播地址抓取——转载
- NLP的“第四范式”之Prompt Learning总结:44篇论文逐一梳理
- Android 高德地图添加线段纹理
- C++实现德州扑克游戏(和电脑一起玩)