位运算以及位运算的应用
位运算
什么是位运算
在计算机系统中,所有数据都是以二进制的形式进行存储,位运算就是对二进制中进行操作。所有的计算都是通过位运算进行实现的。
整数在计算机中
原码
原码是最简单的表示法,对于一个整数而言,最高位代表数据的正负,其他数位代表数据
比如对于一个8位二进制而言 , 00000010
代表有符号整数和没符号整数的 2
10000010
代表有符号整数的的-2
和没符号整数的 130
原码可以让我们更容易看出一个二进制的数值,但是也导致了 正数0和负数0的重合,比如 00000000
和10000000
表示 +0和 -0,在数学中,都表示0.但是与在计算机中没一个数字代表唯一的数位是相悖的,这容易造成数位的加减问题
反码
反码是原码转向补码的中间状态, 正数的反码为本身,负数的反码为除了符号位其他位取反 这解决了加减的问题
比如 -1 + 1,转化为反码就是 111111110
+ 0000000001
加起来为 11111111
得 -0
的反码,但是未解决0的问题。
补码
正数的补码是他原码,也是他的反码。负数的补码是反码加1。 计算机存储都是以补码的形式存储的,
这个就很好解决了0 和 负数加减的问题。
比如 在8位二进制表示的数中, -1
的原码为 10000001
。反码为 11111110
,那么他的补码为 111111111
,从补码我们可以看出,如果 -1 + 1
,可以很简单的转化为 00000000
,对应原码中的正数0,很好的解决了两个0的情况,也很好解决了数据的加减问题。
位运算
位运算的符号
符号 | 描述 | 规则 | 例子 |
---|---|---|---|
& | 与 | 两位想与,两位同时为1则为1 | 0 & 1 = 0, 1& 1 = 1, 0 & 0 = 0 |
| | 或 | 两位想或,有一个为1,则为1 | 0 | 1 = 1, 1 | 1 = 1, 0 | 0 = 0 |
^ | 异或 | 两位相同为0,两位不同为1 | 0 ^ 1 = 1, 0 ^ 0 = 0, 1 ^ 1 = 1 |
~ | 取反 | 0取反为1 ,1 取反为0 | ~0 = 1 , ~1 = 0 |
~(^) | 同或 | 相同为1,相反为0 | 实际上对异或取反,取决于当前一共有多少位 |
<< | 左移 | 向左移动一位 | 1 << 1 = 2, -1 << 1 = -2 |
>> | 右移 | 向右移动一位 | 2 >> 1 = 1 , -2 >> 1 = -1 |
>>> | 无符号右移 | 不带符号向右移动一位 | 2 >>> 1 = 1 ,-2 >>>1 = 2147483647 |
位运算的优先级
优先级 | 符号 | 描述 |
---|---|---|
1 | <<,>> | 左移右移 |
2 | & | 并 |
3 | ^ | 异或 |
4 | | | 或 |
那么问题: 给一串运算 1 | 1 ^ 1 & 1 << 1 等于多少?
1 | 1 ^ 1 & 1 << 1
= 1 | 1 ^ 1 & 2
= 1 | 1 ^ 0
= 1 | 1 = 1
位运算的进阶用法
改变某一位
//将最后一位置为1
a | 1
//将最后一位置为0
a | 1 - 1
//最后一位取反
a ^ 1
//将倒数第n位变为1
a | 1 << n
//将倒数第n位变为0
a & ~(1 << n)
//第k位取反
a ^ (1 << n)
// 右边的第一个0 变为1 10001001 -> 10001011a | (a+1)// 右边的第一个1 变为0 10001010 -> 10001000
a ^ (a & -a)
截取
//取最后一位
a & 1
//取最后第n位
a & 1 << n 或者 a >> n & 1
//取最后n位 a << n 得 10000 减一则为01111末尾全是1
a & (a << n - 1)
//截取最后n位 011111 截取 2位 01111
a >> n
// 取最后一个1得数位 比如 0110 取位 0010a & -a
// 取右边连续的1 比如 100001111 变为 00001111a ^ (a+1)
改变几个数位
//右边连续n位 变为1 1001011 -> 1001111
a | (a << n -1)
//右边连续n位 取反 1001011 -> 1000100
a ^ (a << n - 1)
// 右边连续得1变为0 10001111 -> 1000000a & (a + 1)// 右边连续的0变为1 1001000 -> 10011111
a | (a - 1)
负数的位运算
在进阶用法中我们用到了 a & -a,来取最后一个1的数位, 也就是 00001110
取最后一个1保留其位置,得到00000010
如果一个数是14
那么他正负数的原码,反码,补码可以表示为
原码 反码 补码
00001110 00001110 00001110
10001110 11110001 11110010
那么可以很明显的看出来 补码相与就是最后一个1保留 其他全部为0;得到00000010
位运算的高级用法
判断一个数是否为2的n次幂
if(a & (a - 1)){//是2的整数次幂
}else{//不是2的整数次幂
}
乘法
a >> 1 // a / 2
a << 1 // a * 2
交换两个数
public static void swap(){int a,int b;a ^= b;b ^= a;a ^= b;}
加减法
public int add(int a, int b){while (b != 0){//相同为0 不同为1int tempa = a ^ b;//进位 判断1的数量b = (a & b) << 1;a = tempa;}return a;}
add(1,2);
add(100,200);
乘法
public int muti(int a, int b){int number = 0;int count = 0;while (b != 0){if((b & 1) != 0){number = add(number, a << count);}b = b >> 1;count ++;}return number;}
muti(1,2);
muti(100,200);
在算法中的应用
- https://leetcode-cn.com/problems/count-words-obtained-after-adding-a-letter/solution/by-ubk86jcv4a-wpri/
- https://leetcode-cn.com/problems/missing-two-lcci/solution/java-onshi-jian-o1kong-jian-by-ubk86jcv4-bni7/
- https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/solution/yi-huo-by-ubk86jcv4a-94et/
- https://leetcode-cn.com/problems/palindrome-pairs/solution/yi-huo-da-fa-by-ubk86jcv4a-fng8/
位运算以及位运算的应用相关推荐
- Java从入门到精通08-二进制、位运算、移位运算
Java从入门到精通08-二进制.位运算.移位运算 二进制(Binary)数用0和1两个数字及其组合来表示任何数.进位规则是"逢2进1",数字1在不同的位上代表不同的值,按从右到左 ...
- 64位浮点数_JavaScript 浮点数运算的精度问题
问题描述 在 JavaScript 中整数和浮点数都属于 Number 数据类型,所有数字都是以 64 位浮点数形式储存,即便整数也是如此. 所以我们在打印 1.00 这样的浮点数的结果是 1 而非 ...
- 51单片机实现三位十进制数加减乘除运算
51单片机实现三位十进制数加减乘除运算 一.题目 51单片机IO接口作业 请将附件给出的Proteus图用51单片机完成一个计算器功能. 1.显示采用动态分时8位共阳数码管输出. 2.采用4*4矩阵键 ...
- Java中的位运算符、移位运算
一.位运算 Java中有4个位运算,它们的运算规则如下: (1)按位与 (&) :两位全为1,结果为1,否则为0: (2)按位或 (|) :两位有一个为1,结果为1,否则为0: (3) ...
- java中整形_java中怎样实现60多位整形数字的运算
java中怎样实现60多位整形数字的运算 (2011-09-20 10:57:59) 标签: 杂谈 import java.math.BigInteger; import java.util.Scan ...
- 如何打印int整数的32位二进制数(位运算)
位运算符: <<左移 >>右移 >>>无符号右移 & 与运算 :两位全为1,结果为1,否则为0 | 或运算:两位只要有一个为1,结果为1,否则为0 ...
- 计算机编码二进制0001,二进制学习01(二进制,进制运算,数据宽度,无符号位有符号位编码规则)...
二进制学习01 进制 一.二进制简介 1)什么是二进制? 2)二进制的简写形式 二.进制运算 1)八进制运算表 (1) 加法运算表 (2)乘法运算表 (3)八进制简单运算题 三.数据宽度 1)什么是数 ...
- [GO语言基础] 四.算术运算、逻辑运算、赋值运算、位运算及编程练习
作为网络安全初学者,会遇到采用Go语言开发的恶意样本.因此从今天开始从零讲解Golang编程语言,一方面是督促自己不断前行且学习新知识:另一方面是分享与读者,希望大家一起进步.前文介绍了Golang的 ...
- 位运算——左移右移运算详解
代码#include "stdio.h"char leftshift(char i, int n) {if(n < 0)return -1;return i<<n ...
- 位运算实现加减乘除运算
我们知道,计算机最基本的操作单元是字节(byte),一个字节由8个位(bit)组成,一个位只能存储一个0或1,其实也就是高低电平.无论多么复杂的逻辑.庞大的数据.酷炫的界面,最终体现在计算机最底层都只 ...
最新文章
- hibernate的实现原理
- VTK:Shaders之BozoShader
- chrome开发者工具各种骚技巧
- delphi 鼠标获取窗口句柄_Python 脚本自动对窗口进行截图
- 基于C#的MongoDB数据库开发应用(2)--MongoDB数据库的C#开发
- Software--WCF
- 固态硬盘颗粒有哪些?固态硬盘SLC、MLC、TLC、QLC有什么不同?
- 十一假期,终于过上了理想的生活节奏
- python pipe_Python os.pipe()用法及代码示例
- 对RecyclerView Item做动画
- 永磁同步电机矢量控制电流环参数整定方法----Matlab controlSystemDesigner的使用
- 用几何画板画七边形的方法
- DreamSpark
- 根据网卡MAC地址确定对应交换机端口
- Android--静默安装和静默卸载
- linux scp 限制速度,scp和rsyc限速传输
- 网络电视服务器是什么系统,网络视频直播系统
- html 自动打开qq浏览器,如何保证成功设置默认浏览器-在线帮助-QQ浏览器官网
- l3gd20陀螺仪精度_陀螺仪芯片L3GD20H资料
- 苏州大学9月计算机考试试题,苏州大学计算机组成题库 (9)
热门文章
- vue 项目打包后 浏览器 F12 在source 下不显示 webpack 包
- 【acwing】104. 货仓选址*(贪心|绝对值不等式)
- java全栈系列之JavaSE--JDK的安装以及环境搭建001
- 【3C面板行业大尺寸定位引导解决方案】基于VisionMaster的多相机定位应用案例
- 张艾迪(创始人):世界最高级创始人
- Electric Fences_usaco3.4_皮克定理
- 【专业知识问答】问:什么叫突然短路?为什么突然短路时会产生很大短路电流?
- 免费论文检测 论文查重 软件 系统 论文免费检测 论文抄袭检测大师
- 【业务安全-03】业务逻辑漏洞之暴力破解(Burte Force)
- 2020 Winter Holiday Schedule