位运算
数据在计算机中都是以01的形态进行存储,位运算可以直接对01进行操作,其效率自然很高,在Java源码中是很常见的。这里总结位运算的概念以及常见的操作,后续遇到会补充。
位运算符
位运算是需要使用位运算符的,位运算符有如下几种(本表以java
语言中的位运算为标准):
含义 | 符号 | 简述 |
---|---|---|
按位与 | a & b | 同一得 1 |
按位或 | a | b | 有一得 1 |
按位异或 | a ^ b | 相同得 0 |
按位取反 | ~a | 取反 |
左移 | a << b | 向左移动,低位补零,高位舍弃 |
带符号右移 | a >> b | 向右移动,高位补原有高位,低位舍弃 |
无符号右移 | a >>> b | 忽略符号位,空位都以0补齐 |
位运算优先级
~的优先级最高,其次是<<、>>和>>>,再次是&,然后是^,优先级最低的是|。
位运算符在日常开发中也是 有许多应用场景的,具体场景将在下边代码中展示:
按位或 |
/** * | 按位或 有一得1 * 比较m, n之间,换成二进制后谁的1最多 * 使用 按位或 | 计算 有一得一,与&清零不同的是使用 | 可以置1 * @param m * @param n */ public static int test2(int m ,int n) { // 7:111 8:0001 7|8 = 111(2) | 0001(2) = 1111(2) = 15 // 6:011 7:111 6|7 = 011(2) | 111(2) = 111(2) = 7 while ((m | m+1)<=n) { m = (m | m+1); } return m; }
按位与 &
/** * & 按位与 同一得1 * 判断一个整数n是不是2的x次幂 * 若n&(n-1)=0 则说明n是2的x次幂 * 也可以这样说:循环结束后当ans=1时,说明n时2的x幂 * 按位与 & : 同一得一,可用于清零操作 * @param n * @return ans 表示n转化成二进制数之后,1的个数 */ public static int test1(int n) { int ans = 0; while (n != 0) { ans++; n &= (n-1); System.out.println(n); } return ans; }
异或 ^
/** * ^ 异或 相同得0 * 可用于交换两个变量的数值,不用到带三个变量 * 交换律 * @param a , b */ public static void test3(int a, int b) { a = a ^ b; // a^b ^ b = a b = a ^ b; // a^b ^ a = b a = a ^ b; }
按位取反~
/** * 取反 ~ * 先对原数进行按位取反,然后减1,再进行取反得到一个数,最后加上负号即可 * * 00000000 00000000 00000000 00000100 原值 * 11111111 11111111 11111111 11111011 取反 * 11111111 11111111 11111111 11111010 -1 * 00000000 00000000 00000000 00000101 取反 */ public static void test4() { int a = 4; System.out.print(~4); }
左移 <<
/** * 左移 << * * 00000000 00000000 00000000 00000101 左移2位后,低位补0 * 00000000 00000000 00000000 00010100 转为十进制为 20 */ public static void test5() { int a = 5; System.out.print(a << 2); }
右移 >>
/** * 右移 >> 高位补符号位 * * 00000000 00000000 00000000 00000101 右移2位后,高位补0 * 00000000 00000000 00000000 00000001 转为十进制为 1 */ public static void test6() { int a = 5; System.out.print(a >> 2); }
无符号右移 >>>
/** * 无符号右移 >>> 高位补0 * * >>>和>>的区别是:在执行运算时,>>>运算符的操作数高位补0,而>>运算符的操作数高位移入原来高位的值。 * */ public static void test7() { /** 负数取值: 减一后按位取反 **/ /** * -5 >> 2 情况 * 11111111 11111111 11111111 11111011 -5 的二进制 * 11111111 11111111 11111111 11111110 >> 2 * 10000000 00000000 00000000 00000010 减1,按位取反,值为-2 */ System.out.println(-5 >> 2);// 结果是-2 /** * -5 >>> 2 情况 * 11111111 11111111 11111111 11111011 -5 的二进制 * 00111111 11111111 11111111 11111110 >>> 2, 高位补0,此时为正数 */ System.out.println(-5 >>> 2);// 结果是1073741822 }
本文来自博客园,作者:mingshan,转载请注明原文链接:https://www.cnblogs.com/mingshan/p/17793495.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)