谈到位运算,有些人可能感觉位运算很容易出错,但是位运算可以解决很多问题,所以我们有必要掌握位运算的知识,并能用位运算解决问题。
首先我们熟悉一下位运算的基本操作符(java):
^ (xor) 代表异或,~(not)代表取非,&(and) 代表按位与,|(or)代表按位或
>> 代表右移, << 代表左移,>>>代表无符号右移(用0填充左边的空位)
知道了基本的运算符,我们先看几个小的例子:
1. 0110+0110
在这个例子中,两个相同的数相加,相当于0110*2, 所以我们把0110左移一位就可以了(0110<<1),结果是1100。
2. 0100*0011
因为0100相当于4,相当于2的平方,所以我们把0011左移两位就可以了,结果是1100。
3. 1101^(~1101)
如果我们按位运算它结果是1111,我们可以发现任何一个数异或它本身的非时(a^(~a)),结果是一个1s(1s代表一个1的序列,下面都用1s表示)。
4. 1011&(~0<<2)
这个例子的结果是1000。通过这个例子我们可以总结出一个数x和(~0 << n)进行按位与操作,x的最右边的n为将变为0的序列,换句话说我们清除了x最右边的n位。
通过上面简单的例子我们得到下面的一些基本用法 (0s代表一个全为0的序列):
1. ^ 异或
x ^ 0s = x
x ^ 1s = ~x
x ^ x = 0
2. & 位与
x & 0s = 0;
x & 1s = x;
x & x = x
3. | 按位或
x | 0s = x
x | 1s = 1s;
x | x = x;
4. x & (1 << n) (得到特定位)
1左移n位后我们得到一个类似于00001000的序列,所以通过这个例子我们把x所有位置0除了第n位,从而我们得到了第n位。
5. x | (1 << n) (设置特定位)
同第四个例子,1左移n位后我们得到一个类似于00001000的序列,x按位或00001000后我们能改变第n位,把她设置为1,x中其它位不会受到影响。
6. x & (~ (1 << n)) (清除特定位)
1左移n位后我们得到一个类似于00001000的序列,然后取非,得到11110111,x按位与11110111后我们只把第n位置0,其它位不会改变。类似的还有x &( (x << n) - 1) 和x &(~(-1 >>>(31 - i)))
7. (x & (~(1 << n))) | (y << n) (把x的第n位设置成y)
首先我们把x的第n位设置成0,然后把y左移n位得到一个第i位为y,其余位为0的序列,把这两个数位或就把x的第n位设置成了y。
很多复杂的问题都可以通过这些基本的操作解决。在这里仅仅举几个简单的例子,对于很多题目都可以用位运算解决,希望大家善于思索, 感受位运算的魅力。
1. 给定两个整数 a, b, 如果不用第三个变量, 怎样将两个数的数值交换?
当然我们可以用其他方法解决,但如果我们在面试中用位运算来解决一个问题,也许会让面试官眼前一亮,这道题我们可以用异或来解决。
首先我们令a = a ^ b; 然后b = a ^ b, 相当与 b = a ^ b ^ b = a ^ 0 = a; 最后我们令 a = a ^ b, 此时b = a, 也就是 a = a ^ b ^ a = b。从而完成了两个值的交换。
2. 给定两个整数A, B,写一个方法确定需要几次换位才可以将A变为B。
比如 A: 11010 B: 01100 输出:3
我们首先要知道那些位需要替换,我们很容易想到异或这个功能,A^B,相同的位异或为0,不同的位异或为1,所以我们只需要确定异或之后的数有几个1即可。我们怎么确定呢?上面讲到了如何清除特定位,这里是个特例,例如A^B = x, 我们让x&(x-1),这个操作清除了x最右边的1,我们通过一个循环确定次数,直到x为0结束。代码如下:
public int bitSwapNums(int a, int b) {
int count = 0;
for(int i = a ^ b; i > 0; i= i & (i - 1)){
count ++;
}
return count;
}
位运算的应用很灵活,我们也可以这样实现
public int bitSwapNums(int a, int b) {
int count = 0;
for(int i = a ^ b; i > 0; i = i >> 1) {
count += i & 1;
}
return count;
}
每次循环i右移一位,通过与1进行位与得到1的个数。
分享到:
相关推荐
位运算不仅限于这些基本操作,还有如`&=`、`^=`、`|=`、`和`>>=`这样的复合赋值操作符,它们分别对应于按位与、按位异或、按位或、左移和右移后的赋值。 在实际应用中,位运算常常用于: 1. 不使用临时变量交换两个...
德州仪器(Texas Instruments,简称TI)出版的《运算放大器实例讲解.pdf》文档详细介绍了运算放大器在模拟电路设计中的应用,提供了一系列经过仿真验证的电路实例。本文将对文档中提及的关键知识点进行详解。 首先...
本文将详细解析位运算的概念、运算符、应用以及注意事项。 首先,位运算是基于二进制位的操作,它直接对数据的二进制表示进行处理。在ACMer(参加ACM/ICPC国际大学生程序设计竞赛的选手)中,熟练掌握位运算能够...
通过深入学习和实践这些源码,开发者可以更深入地理解C#中的基本操作,并为更复杂的编程任务奠定坚实的基础。无论是简单的计算还是处理大量数据,理解和掌握这些基本概念都是必不可少的。在实际项目中,这些基础知识...
本篇文章将深入探讨Java中的位运算,包括其基本概念、常用操作符以及实际应用。 一、位运算的基本概念 在计算机内部,所有的数据都是以二进制形式存储的。位运算就是对这些二进制位进行操作。一个整数在计算机内存...
MATLAB数组运算是MATLAB的核心功能之一,本文将对MATLAB数组运算的基本概念、数组创建、数组运算、数组操作函数等进行详细介绍。 数组的定义和类型 在MATLAB中,数组是一种基本数据类型,用于存储和操作数据。...
在这个VERILOG实现的4位ALU模块中,设计者通过编程实现了加、减、与、或、非五种基本运算。下面将详细解释这些知识点。 1. **VERILOG**: VERILOG是一种硬件描述语言(HDL),用于设计和验证数字系统,如微处理器...
本章节将详细介绍MATLAB数据的特点、表示方法、基本运算等方面的内容。 2.1 MATLAB数据的特点 MATLAB数据可以分为多种类型,包括数值数据、逻辑数据、函数句柄、数组、结构体、单元数据等。其中,数值数据又可以...
本文将深入讲解Java中的位运算,并通过雪花算法的应用实例来进一步阐述其重要性和用法。 1. **位运算概念** 位运算涉及到对整数类型(byte, short, int, long)的二进制表示进行操作。Java提供了六种基本的位...
1. Java的位运算符和位运算,包括基本操作和实际应用。 2. 使用Java构建图形用户界面,可能涉及Swing或JavaFX库,以及组件的使用和事件处理。 3. Eclipse IDE的使用,包括项目配置和构建过程。 4. 对象导向编程,...
本文将探讨一种基于位运算的简单加密方法,通过位移、异或等基本操作实现数据的加密和解密。这个实例023 - 加密可以这样简单(位运算)揭示了如何利用编程语言中的位运算来创建一个简单的加密算法。 位运算在计算机...
位片式运算器AMD2900(4位/片)是一种位片式运算器。浮点运算器阶码部件、尾数部件、数据总线、阶码运算部件、寄存器的使用都是浮点运算器的重要组成部分。 运算器ALU组成与实例是计算机组成原理中的一个重要部分,...
这里我们将深入讲解单片机的P0口操作、按位异或运算以及其实现方法。 首先,单片机的P0口通常作为并行数据总线使用,它可以同时传输8位二进制数据。P0口的每一位都能被独立地设置为输入或输出,这使得它非常适合...
16位CPU可能会包含加法、减法、逻辑运算、分支和加载/存储指令等基本操作。 3. **数据通路和控制单元**:数据通路负责执行指令,包括算术逻辑单元(ALU)、寄存器文件、数据总线和控制信号。控制单元则根据指令生成...
从给定的文件“matlab矩阵运算实例.txt”中,我们可以提炼出一系列关于MATLAB中矩阵操作的关键知识点,这些知识点不仅涵盖了基本的矩阵加减乘除运算,还涉及到了更高级的运算方式。 ### 基本矩阵运算 #### 加法与...
Matlab 矩阵运算提供了各种矩阵生成、矩阵操作、矩阵基本运算和线性代数运算的命令和函数,帮助用户快速高效地进行矩阵运算。 一、矩阵生成 Matlab 提供了多种方式来生成矩阵,包括: * 直接输入:使用中括号 [] ...
本文将详细介绍C#中的位运算及其实例计算,帮助开发者理解和掌握这些基本概念。 位运算通常应用于整型数据,因为它涉及到二进制表示。在计算机内存中,所有数据最终都是以二进制(0或1)形式存储的。C#提供了五种...
本部分将从二进制的基础知识、C语言位运算的应用、数据的二进制表示以及位运算在编程中的具体实现等方面进行深入解析。 首先,二进制是一种基数为2的数制,使用两个数字0和1来表示数值,其进位规则是逢二进一,借位...
位运算是指直接对这些二进制位进行操作的运算,包括与(&)、或(|)、异或(^)和非(~)四种基本运算。 2. **位运算符详解**: - **按位与(&)**:对应位上都是1时结果才为1,否则为0,类似于逻辑与。在灯光开关的例子中...