位运算(&、|、^)

本文介绍了位运算的基础知识,包括与(&)、或(|)、异或(^)、左移(<<)、右移(>>)等操作,并探讨了它们在判断奇偶数、交换变量、求绝对值等方面的应用。通过异或操作解决实际编程问题,如找到数组中唯一重复或单独出现的数字,计算二进制中1的个数,以及判断是否为2的整数次方。

基础知识:

1.在处理整型数值时,可以直接对数值的各个位进行操作,即可用屏蔽技术获得整数中的各个位

2.&(与:都为1结果才为1)、|(或:有一个为1结果为1)、^(异或:二者不同时结果为1)、~(非)

3.>>(右移)、<<(左移)将二进制位进行右移或左移操作

4.>>>用0填充高位,>>用符号位填充高位,没有<<<运算符

5.对于int型,1<<35与1<<3相同(取模),左侧操作数是long型时需对右侧作模64


应用: 

1.判断奇偶数

if (x&1)==1  x为奇数; 
if (x&1)==0  x为偶数;

因为偶数的最后一位是0,奇数的最后一位是1

2.获取二进制位是1还是0

将1左移到那个位上,其他位都是0,作&运算就相当于把其他位屏蔽掉,因为0与任何数作&都是0,将结果再移动到最低位。

3.交换两个整数变量的值

4.不用判断语句,求整数的绝对值

5.异或,可以理解为不进位加法: 1+1=0   0+0=0   1+0=1


题目:

1.唯一成对的数

【问题描述】1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间。

【算法1】异或(^)消除偶数个出现次数的字母   A^A=0   B^0=B   A^A^B^C^C=B

1……K K……1000 ^(1 ^……K……1000)这样K就有3个

【代码】先求1~n-1连续的异或

【算法2】若题目没有不能开辅助空间的约束时,可以开一个辅助空间,辅助数组下标对应数值,记录数字出现的次数。

2.找出落单的那个数

【问题描述】一个数组里除了某一个数字之外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字。

【算法】与上一题相似,出现2次的就被异或掉了。好补或者是知道范围的可以用异或的方法,其他的可以用数组下标法。

3.二进制中1的个数

【问题描述】请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例:9的二进制表示为1001,有2位是1

【算法1】探测某一位是不是1的方法上图所画方法,&运算完成之后正好等于1移位过去的数值

【代码】

【算法2】将n右移,与1&,1不动

【代码】

【算法3】(x-1)&x的效果是消掉n末尾的1

 =0是终止条件

【代码】

 5.用一条语句判断一个整数是不是2的整数次方

【算法】是2的整数次方=2进制表示中只有1个1

if  (((n-1)&n)==0) 
    是2的整数次方;

6.将整数的奇偶位互换

 【算法】&运算特点:与1&保留,与0&消除

 分别保留奇偶位,再将结果 ^ 

 每4位2进制可以用16进制表示

7.0-1间浮点实数的二进制表示

【问题描述】给定一个介于0和1之间的实数,(如0.625),类型为double,打印他的二进制表示(0.101,因为小数点后的二进制分别表示0.5、0.25、0.125……)。如果该数字无法精确地用32位以内的二进制表示,则打印“ERROR”

【算法】浮点数×2的方式看个位

【代码】

 8.出现K次与出现一次

【问题描述】数组中只有一个数出现了1次,其他数都出现了K次,请输出只出现了一次的数

【算法】2个2进制数做不进位相加=0;10个10进制数不进位相加=0;K个K进制数不进位相加=0

Integer.toString(i,radix) ; 10进制转radix进制

【代码】

&lt;think&gt;我们正在讨论的是双目运算符的分类。用户询问的是&amp;、|、^这三个运算符在双目运算符中的分类。 根据常见的编程语言(如C、C++、Java等)的规则: - &amp;、|、^ 这三个运算符在大多数语言中都有两种用途:位运算和逻辑运算(但注意,逻辑运算通常使用&amp;&amp;和||)。 但是,从用户提供的引用中我们可以得到一些线索: 引用[1]提到:&ldquo;&amp; | ^ 运算符。位运算符与赋值运算符可以组成复合赋值运算符。例如: &amp;=, |=, &gt;&gt;=, &lt;&lt;=, &and;=&rdquo;。这里明确将&amp;、|、^称为位运算符。 引用[2]在介绍逻辑运算符时,使用的是&amp;&amp;、||、!,而在后面提到&ldquo;位运算&rdquo;,但没有具体列出,但引用[1]已经明确它们是位运算符。 引用[3]在逻辑运算符部分也只提到了&amp;&amp;、||、!。 因此,我们可以得出结论: 在双目运算符中,&amp;、|、^通常被归类为位运算符(bitwise operators)。位运算符属于独立的类别,有时也被归入算术运算符的大类(因为位运算本质上是对整数的二进制形式进行算术运算),但更常见的做法是将位运算符单独分类。 然而,在有些语言中(例如Java、C#),&amp;和|也可以用于布尔值之间的运算,此时它们执行的是非短路的逻辑运算。但是,它们的主要用途还是位运算,所以通常分类为位运算符。 另外,注意位运算符和移位运算符(&lt;&lt;, &gt;&gt;, &gt;&gt;&gt;)通常一起被归为位运算类别。 所以,对于问题: &amp; 按位与(Bitwise AND) | 按位或(Bitwise OR) ^ 按位异或(Bitwise XOR) 它们属于位运算符(Bitwise Operators),而位运算符通常与算术运算符、移位运算符等并列。 但是,在传统的运算符分类中,有时会将位运算符和移位运算符统称为位运算运算符。在更细致的分类中,移位运算符单独为一类(移位运算符),而&amp;、|、^则归为位运算符(狭义)。 因此,我们可以这样回答: 在双目运算符中: &amp;、|、^ 属于位运算符(Bitwise Operators),它们作用于整数类型的操作数,对操作数的每一位进行运算。 注意:它们也可以用于布尔值(在支持此操作的语言中),但此时它们执行的是非短路的逻辑运算,不过仍然归类为位运算符(因为其行为是按位进行的,即使是对布尔值,布尔值也可以视为一位的位模式)。 另外,赋值运算符中还有复合赋值形式:&amp;=, |=, ^=,这些属于赋值运算符(复合赋值运算符)。 所以,严格来说,&amp;、|、^作为独立的运算符使用时,它们属于位运算符;当它们与赋值符号结合成&amp;=、|=、^=时,属于赋值运算符。 因此,我们回答: - &amp;、|、^ 作为双目运算符时,属于位运算符(有时位运算符被归入算术运算的大类,但通常单独分类)。 - 它们不属于算术运算符(算术运算符是+、-、*、/、%等)、移位运算符(移位运算符是&lt;&lt;、&gt;&gt;、&gt;&gt;&gt;)、关系运算符(&gt;、&lt;、==等)、逻辑运算符(&amp;&amp;、||)、赋值运算符(=、+=等,但注意复合赋值形式属于赋值运算符)或条件运算符(?:)。 因此,我们需要明确位运算符是一个独立的类别。 根据以上分析,回答如下:&lt;/think&gt;### &amp;、|、^ 运算符分类详解 在双目运算符中,`&amp;`、`|`、`^` 属于**位运算符**(Bitwise Operators),这类运算符直接对操作数的二进制位进行运算。以下是具体分类说明: #### 1. **位运算符**(核心分类) | 运算符 | 名称 | 运算规则 | 示例(假设 `a=5`(二进制 `0101`), `b=3`(二进制 `0011`)) | |--------|--------------|--------------------------------------------------------------------------|--------------------------------------------------------| | `&amp;` | 按位与 | 两个位都为1时结果才为1 | `a &amp; b = 0101 &amp; 0011 = 0001` &rarr; 结果 `1` | | `|` | 按位或 | 任意一个位为1时结果为1 | `a | b = 0101 | 0011 = 0111` &rarr; 结果 `7` | | `^` | 按位异或 | 两个位不同时结果为1 | `a ^ b = 0101 ^ 0011 = 0110` &rarr; 结果 `6` | **关键特性**: - 操作数要求:整数类型(如 `int`, `long`, `byte` 等) - 运算级别:低于算术运算符,高于逻辑运算符[^1][^2] - 常见用途: - 加密算法(异或加密) - 权限控制(位掩码) - 底层硬件操作 #### 2. **其他分类的关联性** - **逻辑运算符**: 虽然 `&amp;` 和 `|` 有对应的逻辑运算符 `&amp;&amp;` 和 `||`,但两者本质不同: - 位运算符 `&amp;`/`|`:操作整数,按位计算 - 逻辑运算符 `&amp;&amp;`/`||`:操作布尔值,支持短路求值[^3] ```java // 位运算(整数操作) int x = 5 &amp; 3; // 结果:1 // 逻辑运算(布尔操作) boolean y = (5 &gt; 3) &amp;&amp; (2 &lt; 4); // 结果:true ``` - **赋值运算符**: 可与赋值符号结合形成**复合赋值运算符**(如 `&amp;=`, `|=`, `^=`): ```c a &amp;= b; // 等价于 a = a &amp; b; a ^= 2; // 等价于 a = a ^ 2; ``` 此时属于赋值运算符类别[^1]。 #### 3. **与其他运算符类别的区别** | 类别 | 典型运算符 | 与 `&amp;|^` 的区别 | |--------------|--------------|-----------------------------------------| | 算术运算符 | `+ - * / %` | 操作数值,非二进制位 | | 移位运算符 | `&lt;&lt; &gt;&gt; &gt;&gt;&gt;` | 移动位位置,非位间运算 | | 关系运算符 | `== &gt; &lt;` | 返回布尔值,非数值结果 | | 条件运算符 | `? :` | 三目运算符,非双目运算 | &gt; ⚠️ 注意:在部分语言(如 C/C++)中,`&amp;` 还可作为取地址符(单目运算符),此时不属于位运算范畴。 ### 总结分类 | 运算符 | 主要类别 | 次要类别(复合形式) | 操作数类型 | |--------|------------|----------------------|------------| | `&amp;` | 位运算符 | 赋值运算符(`&amp;=`) | 整数 | | `|` | 位运算符 | 赋值运算符(`|=`) | 整数 | | `^` | 位运算符 | 赋值运算符(`^=`) | 整数 |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值