位运算与简单应用

一.位运算的基本概念:

首先,位运算是针对二进制的,(数字本来int,4字节,下面假设为1字节)。比如数字12,它的二进制本来是: 

               0000 0000 0000 0000 0000 0000 0000 1100

因为前面的数字大都是0,所以为了简写,我们保留1字节。在下文中我们12就写成:

               0000 1100


二.进制的介绍

  • 进制: 按权展开求和
  • 十进制(0~9):123.45 = 110^2 + 210^1 + 310^0 + 410^-1 + 5*10^-2
  • 二进制(0~1):1010.1 = 2^3+2^1+2^-1=10.5
  • 八进制(0~7):123 = 1*8^2 + 2*8^1+3 = 83
  • 十六进制(0~9,a~f/A~F):123=1*16^2+2*16+3=256+35=291
  • 人(十进制) 计算机(二进制)
  • 人能直接使用二进制吗? 01011010111101101111010110101011,容易看错, 人不能直接使用
  • 二进制能转成十进制吗? 01011010111101101111010110101011,计算量太大:
int main()
{int a = 0x10;//十六进制int b = 20;//十进制int c = 020;//八进制printf("%d,%d,%d\n", a, b, c);//16,20,16printf("%x\n", a);//%x:输出十六进制数字printf("%x\n", 20);//14,printf("%c,%d,%x\n", 65, 65, 65);//'A',65,41printf("%x,%X\n", 20000, 20000);//4e20,4E20//练习//0x124->转二进制->转八进制->转十进制//0x124->0001 0010 0100 -> 444->292return 0;
}

int main()
{int a = 20;int b = 024;//0开头的数据表示八进制数字int c = 0x14;//0x开头的数据表示十六进制int d = 0b10100;//0b开头的数据表示二进制 (新标准增加的)printf("%d,%d,%d,%d\n",a,b,c,d);return 0;
}


三.具体内容

我们以数字12,13举例, 

  • 12:0000 1100
  • 13:0000 1101
  • ~12:1111 0011 按位取反
  • 12&13:0000 1100 按位与,相同的位都为1才为1
  • 12 | 13:0000 1101 按位或,相同的位只要有1就为1
  • 12^13:0000 0001 按位异或,相同的位不一样就为1
  • 12<<1:000 11000 按位左移,右边补0(离符号太远) 24=12*2 左移相当于乘法(正数) 乘以2的位移次方
  • 12>>1:00000 110 右移,左边补符号位(如果是无符号数补0,有符号数符号位为0则补0,为1则补 1) 6=12/2 右移相当于除法(正数),除以2的位移次方

四.应用

具体运算如下:下面的运算都是针对二进制

  • 去掉最后一位 | (101101->10110) | x >> 1
  • 在最后加一个0 | (101101->1011010) | x << 1
  • 在最后加一个1 | (101101->1011011) | (x << 1) | 1
  • 把最后一位变成1 | (101100->101101) | x | 1
  • 把最后一位变成0 | (101101->101100) | (x >> 1) << 1 x & ~1
  • 最后一位取反 | (101101->101100) | x ^ 1
  • 把右数第k位变成1 | (101001->101101, k = 3) | x | (1 << (k - 1))
  • 把右数第k位变成0 | (101101->101001, k = 3) | x & 111011->x & ~(1 << (k - 1))
  • 右数第k位取反 | (101001->101101, k = 3) | x ^ 100->x ^ (1 << (k - 1))
  • 1.确定符号 2.确定数字 3.构造数字
  • 得到1 | 1 (这一位是1)
  • 得到0 & 0(这一位是0)
  • 取反 ^ 1
  • 取最右边的1位 | (1101101->1) | x & 1, x % 2
  • 取末三位 | (1101101->101) | x & 111->x & ((1 << 3) - 1), x & 7
  • 取末k位 | (1101101->1101, k = 4) | x & ((1 << k) - 1)
  • 取右数第k位 | (1101101->1, k = 4) | (x >> (k - 1)) & 1

五. 题目

  • 编程1:

       所有的数字成对,只有一个数字只出现一次,找到它

//1^3^5^3^1=1^1^3^3^5=5
//找打单的数字
int SingleNum(int* arr, int len)//O(n)
{int tmp = 0;for (int i = 0; i < len; i++)tmp ^= arr[i];return tmp;
}
int main()
{int arr[] = { 1,5,3,7,9,6,1,3,9,6,5 };//所有的数字成对,只有一个数字只出现一次,找//到它//算法1:1.排序;2.遍历 O(nlogn)//算法2:从头到尾按位异或(按位异或相同的数字为0,5^5==0)int n = SingleNum(arr, sizeof(arr) / sizeof(arr[0]));printf("%d\n", n);return 0;
}
  •  编程应用2:

统计一个数字二进制1的个数.例如9转为二进制是0000 1001,那么二进制中1的个数为2.

  • 算法1:利用%2和/2
//统计十进制数字中1的个数例如1231212->3 得个位n%10 ,丢个位n/=10
//统计二进制中1的个数
int Bits(unsigned int n)//-1 ->11111111111111111111111111111111
{int count = 0;//计数器while (n != 0){if (n % 2 == 1)count++;n /= 2;}return count;
}
int main()
{printf("%d\n", Bits(12345678));printf("%d\n", Bits(0x12345678));//1+1+2+1+2+2+3+1printf("%d\n", Bits(-1));//32return 0;
}
  •  算法2:利用位运算,统计最右边1的个数
int Bits2(unsigned int n)
{//n&1:得到二进制右数第1位; n>>=1:丢弃右数第1位int count = 0;while (n != 0)//0x10000000{count += n & 1;n >>= 1;}return count;
}
int main()
{printf("%d\n", Bits(12345678));printf("%d\n", Bits(0x12345678));//1+1+2+1+2+2+3+1printf("%d\n", Bits(-1));//32return 0;
}
  •  算法3:利用x&(x-1)进行统计

 

int Bits(unsigned int n)
{int count = 0;while (n != 0){count++;n &= n - 1; //丢弃二进制最右边的1}return count;
}
int main()
{printf("%d\n", Bits(12345678));printf("%d\n", Bits(0x12345678));//1+1+2+1+2+2+3+1printf("%d\n", Bits(-1));//32return 0;
}
  • 算法四:
int func(unsigned i) //统计二进制1的个数
{unsigned temp = i;temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa) >> 1);temp = (temp & 0x33333333) + ((temp & 0xcccccccc) >> 2);temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0) >> 4);temp = (temp & 0xff00ff) + ((temp & 0xff00ff00) >> 8);temp = (temp & 0xffff) + ((temp & 0xffff0000) >> 16);return temp;
}
int main()
{printf("%d\n", func(0x7f530829));//3+4+2+2+1+1+2=15return 0;
}

 六.总结:

变1: x | (其它位是0,当前位是1)

变0 : x&(其它位是1,当前位是0)

取反:x ^ (其它位是0,当前位是1)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/177527.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

火影忍者游戏攻略大公开!成为忍者大师的秘诀揭秘

大家好&#xff01;作为火影忍者游戏的玩家&#xff0c;我们都希望能够在游戏中成为优秀的忍者大师&#xff0c;战胜强大的对手。为了帮助大家实现这一目标&#xff0c;我想分享一些实用的攻略和技巧。 首先&#xff0c;熟悉忍者技能是成为忍者大师的基础。在火影忍者游戏中&am…

C语言_自定义类型详解

文章目录 前言一.结构体的声明1.1结构体的基础知识1.2结构的声明1.3特殊声明1.4结构体的自引用在结构中包含一个类型为该结构本身的成员是否可以&#xff1f;正确的自引用方式匿名结构体类型和typedef的结合形式 1.5 结构体变量的定义和初始化结构体定义与初始化结构体里嵌套结…

【Linux进程】再谈软件—操作系统(Operator System)

目录 操作系统(Operator System) 概念 设计OS的目的 如何理解 "管理"——先描述再组织 系统调用和库函数概念 总结 操作系统(Operator System) 概念 任何计算机系统都包含一个基本的程序集合&#xff0c;称为操作系统(OS)。 笼统的理解&#xff0c;操作系统…

【python】路径管理+路径拼接问题

路径管理 问题相对路径问题绝对路径问题 解决os库pathlib库最终解决 问题 环境&#xff1a;python3.7.16 win10 相对路径问题 因为python的执行特殊性&#xff0c;使用相对路径时&#xff0c;在不同路径下用python指令会有不同的索引效果&#xff08;python的项目根目录根据执…

利用Graviton2和S3免费套餐搭建私人网盘

网盘是一种在线存储服务&#xff0c;提供文件存储&#xff0c;访问&#xff0c;备份&#xff0c;贡献等功能&#xff0c;是我们日常中不可或缺的一种服务。很多互联网公司都为个人和企业提供免费的网盘服务。但这些免费服务都有一些限制&#xff0c;比如限制下载速度&#xff0…

下载树莓派对应的64位Ubuntu系统步骤

说点废话&#xff1a;因为ros2需要安装在64位Ubuntu上面&#xff0c;所以安装64位最合适&#xff1b; 第一步打开https://cn.ubuntu.com/ 网站&#xff1b;选择下载--->iot----> 选择这个镜像文件下载。我觉得镜像文件是img格式的&#xff0c;跟iso文件区别是&#xff…

vue详细安装教程

这里写目录标题 一、下载和安装node二、创建全局安装目录和缓存日志目录三、安装vue四、创建一个应用程序五、3x版本创建六、创建一个案例 一、下载和安装node 官网下载地址&#xff1a;https://nodejs.org/en/download 选择适合自己的版本&#xff0c;推荐LTS&#xff0c;长久…

【计算机网络】计算机网络中的基本概念

文章目录 局域网LAN基于网线直连基于集线器组建基于交换机组建基于交换机和路由器组建 广域网WANIP地址端口号协议为什么要有协议知名协议的默认端口 五元组协议分层TCP/IP五层模型封装和分用 网络互连就是将多台计算机连接在一起&#xff0c;完成数据共享。数据共享本质是网络…

C++设计模式_23_Command 命令模式

我们将Command 和Visitor归为“行为变化”模式。 Command 命令模式与函数对象十分类似&#xff0c;但在C主流框架中&#xff0c;函数对象&#xff08;function object&#xff09;应用的更为广泛。 文章目录 1. “行为变化”模式1.1 典型模式 2. 动机( Motivation )3. 模式定义…

【Leetcode】【消失的数字】【C语言】

方法一&#xff1a;按位异或&#xff08;找单身狗&#xff09; 我们知道&#xff1a;按位异或^操作原则&#xff1a;相同为零&#xff0c;相异为一 所以 0^aa a ^a0 a ^bb ^a int missingNumber(int* nums, int numsSize){ int i 0; int tem1 0,tem20; for (i 0;i < nu…

大厂面试题-介绍一下自己对Netty

目录 用三点来简单的介绍下Netty&#xff1a; 面试官&#xff1a;哦&#xff0c;还不错&#xff0c;那你在说说为什么要用Netty&#xff1f; 面试官&#xff1a;那你在通俗地说一下Netty可以做什么事情&#xff1f; 面试官&#xff1a;那&#xff0c;在说说Netty有几种线程…

XUbuntu22.04之simplenote支持的Markdown语法总结(一百九十一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

linux下df -h 命令一直卡住的解决方法

在Linux中&#xff0c;偶尔遇到用 df -h 查看磁盘情况时&#xff0c;一直卡住无法显示结果。 解决方法&#xff1a; 1、首先使用strace追踪到底执行到哪里卡住 $ strace df -h 2、如果没有strace命令则进行安装 $ yum install strace -y 3、显示出卡住的地方&#xff0c;如…

SpringBoot源码透彻解析—bean生命周期

先跟一段debug再看总结&#xff1a; 1 创建实例 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation&#xff08;自定义一个对象或者代理对象&#xff09;createBeanInstance&#xff08;创建实例&#xff09;MergedBeanDefinitionPostProcessor.postProcess…

编程怎么学才高效?初学编程怎么样才容易入门?

学习编程并提高编程能力需要一种结构化的方法&#xff0c;其中包括理解基础概念、实践、反馈和持续学习。以下是一些高效学习编程的策略&#xff1a; 理解基础概念&#xff1a;在学习编程的初期&#xff0c;理解基础概念非常重要。这包括学习编程语言的基本语法、数据类型、控…

Java调用HTTPS接口,绕过SSL认证

1&#xff1a;说明 网络编程中&#xff0c;HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是一种通过加密的方式在计算机网络上进行安全通信的协议。网络传输协议&#xff0c;跟http相比更安全&#xff0c;因为他加上了SSL/TLS协议来加密通信内容。 Java调…

算法与数据结构-分治算法

文章目录 什么是分治算法分治算法应用举例分析分治思想在海量数据处理中的应用 什么是分治算法 分治算法&#xff08;divide and conquer&#xff09;的核心思想其实就是四个字&#xff0c;分而治之 &#xff0c;也就是将原问题划分成 n 个规模较小&#xff0c;并且结构与原问…

JavaEE入门介绍,HTTP协议介绍,常用状态码及含义,服务器介绍(软件服务器、云服务器)

一、JavaEE入门 JavaEE&#xff08;Java Enterprise Edition&#xff09;&#xff0c;Java企业版&#xff0c;是一个用于企业级web开发&#xff08;不需要使用控制台&#xff09;平台。最早由Sun公司定制并发布&#xff0c;后由Oracle负责维护。 JavaEE平台规范了在开发企业级w…

3D RPG Course | Core 学习日记三:Navigation智能导航地图烘焙

前言 前面我们已经绘制好了一个简单的地图场景&#xff0c;现在我们需要使用Navigation给地图做智能导航&#xff0c;以实现AI自动寻路&#xff0c;以及设置地图的可行走区域以及不可行走区域&#xff0c;Navigation的基础知识、原理、用法在Unity的官方文档&#xff0c;以及网…

cocos creator,vscode打开脚本报错,找不到cc模块问题

cocosCreator&#xff0c;用VSCODE打开写脚本代码的时候&#xff0c;会误报飘红&#xff0c;但实际上能正常运行。 我的版本是当前最新版本的3.8.1 解决方案: 在CocosCreator 的安装目录下 C:\ProgramData\cocos\editors\Creator\3.8.1\resources\resources\3d\engine\bin.dec…