Java Bitwise Operators
Java中的位操作指定包括:
~ 按位非(NOT)
& 按位与(AND)
| 按位或(OR)
^ 按位异或(XOR)
>> 右移
>>> 无符号右移
<< 左移
前面几个都非常简单,主要是移位操作比较容易出错.
首先要搞清楚参与运算的数的位数,如int的是32位。long的是64位。
如int i = 1;
i的二进制原码表示为:
00000000000000000000000000000001
long l = 1;
l的二进制原码表示为:
0000000000000000000000000000000000000000000000000000000000000001
二、
正数没有反码、补码,也可以说正数的反码、补码跟原码一样。
负数的反码为原码逐位取反,
如int i = -1;
10000000000000000000000000000001,最高位是符号位。正数为0,负数为1。
逐位取反后:
01111111111111111111111111111110即反码。
反码加1:
01111111111111111111111111111111即补码。
负数都是用补码参与运算的。得到的也是补码,需要减1取反获得原码。
三、常用的位运算符--0在位运算中是比较特殊的。
^ 异或。 相同为0,相异为1; 任何数与0异或都等于原值。
& 与。 全1为1, 有0为0;任何数与0异或都等于0。
| 或。 有1为1, 全0为0。任何数与0或都等于原值。
<<左移。 补0。
>> 右移。 符号位是0补0,是1补1。
>>>无符号右移。补0。
~ 非 逐位取反
四、负数参与的运算,得到的是补码,需要将补码先减1,然后逐位取反,得到原码。即为运算结果。
0例外,如果得到的是0,则不需减1和取反。
另外,两个正数运算后得到的就是原码,不需减1和取反。
举例:
1^-1,
-1
10000000000000000000000000000001--原码
01111111111111111111111111111110--反码
01111111111111111111111111111111--补码
1
00000000000000000000000000000001--原码
则1^-1等于
01111111111111111111111111111111^
00000000000000000000000000000001=
01111111111111111111111111111110--补码
01111111111111111111111111111101--反码
10000000000000000000000000000010--原码==-2
即1^-1=-2
举例:
1^-2
-2
10000000000000000000000000000010--原码
01111111111111111111111111111101--反码
01111111111111111111111111111110--补码
1
00000000000000000000000000000001--原码
则1^-2等于
01111111111111111111111111111110^
00000000000000000000000000000001=
01111111111111111111111111111111--补码
01111111111111111111111111111110--反码
10000000000000000000000000000001--原码==-1
1.<<
逻辑左移,右边补0,符号位和其他位一样.
正数:
x<<1一般相当于2x,但是可能溢出.
溢出范围: 230~(231-1) 二进制表示 010000...000到01111....1111,移位后最高为变为1了,变成负数了.
负数:
x<<1一般也相当于2x,也有可能溢出.所以, x*32可以写成x<<5
溢出范围: -231~-(230+1)二进制表示10000...000到101111...1111,移位后最高为变成0了,变成正数了.
2.>>
算术右移,和上面的不对应,为正数时左边补0,为负数时左边补1.
x>>1,相当于x/2,余数被舍弃,因为这个是缩小,所以不会溢出.
不过有一点要注意: -1右移多少位都是-1.
另外舍弃的余数是正的, 3>>1=1 舍弃的余数是1.
-3>>1=-2 舍弃的余数也是1,而不是-1.
对于正数 x>>1和x/2相等
对于负数 x>>1和x/2不一定相等.
3.>>>
逻辑右移,这个才是和<<对应的
这个把符号位一起移动,左边补0
对于正数,>>>和>>是一样的
对于负数,右移之后就变成正数了.
可以使用Integer.toBinaryString(int i)来看01比特,更加直观.
考虑下面的代码:
for (val = 0; val < 100000; val +=5) { alterX = val * 8; myResult = val * 2; }
用移位操作替代乘法操作可以极大地提高性能。下面是修改后的代码:
for (val = 0; val < 100000; val += 5) { alterX = val << 3; myResult = val << 1; }
修改后的代码不再做乘以8的操作,而是改用等价的左移3位操作,每左移1位相于乘以2。相应地,右移1位操作相当于除以2。值得一提的是,虽然移位操作速度快,但可能使代码比较难于理解,所以最好加上一些注释。
无符号右移位操作符“>>>”在将bit串右移位时,从bit串的最左边填充0,这和带符号右移位操作符“>>”不同。“>>”在将bit串右移位时,从bit串的最左边填充原来最左边的位。也就是说,bit串原来最左边的位是符号位,如果为1,则在带符号右移时最左边始终填充1;如果为0,则在带符号右移时最左边始终填充0。
移位操作符的例子见下表。
操作 | 结果 | 说明 |
00110010 << 2 | 11001000 | 右边始终填充0 |
00110010 >> 2 | 00001100 | 结果一样 |
00110010 >>> 2 | 00001100 | |
10110010 >> 2 | 11101100 | 结果不同 |
10110010 >>> 2 | 00101100 |
“按位与”操作符“&”对两个bit串按位进行逻辑与,“按位或”操作符“|”对两个bit串按位进行逻辑或,“按位异或”操作符“^”对两个bit串按位进行异或操作。运算规则如下表所示。
按位与 | 按位或 | 按位异或 |
0 & 0 = 0 | 0 | 0 = 0 | 0 ^ 0 = 0 |
0 & 1 = 0 | 0 | 1 = 1 | 0 ^ 1 = 1 |
1 & 0 = 0 | 1 | 0 = 1 | 1 ^ 0 = 1 |
1 & 1 = 1 | 1 | 1 = 1 | 1 ^ 1 = 0 |
“>> 右移,高位补符号位”;
“>>> 无符号右移,高位补0”;
“<< 左移”;
例子:
-5>>3=-1
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1111 1111
其结果与 Math.floor((double)-5/(2*2*2)) 完全相同。
-5<<3=-40
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1101 1000
其结果与 -5*2*2*2 完全相同。
5>>3=0
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0000
其结果与 5/(2*2*2) 完全相同。
5<<3=40
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0010 1000
其结果与 5*2*2*2 完全相同。
-5>>>3=536870911
1111 1111 1111 1111 1111 1111 1111 1011
0001 1111 1111 1111 1111 1111 1111 1111
无论正数、负数,它们的右移、左移、无符号右移 32 位都是其本身,比如 -5<<32=-5、-5>>32=-5、-5>>>32=-5。
一个有趣的现象是,把 1 左移 31 位再右移 31 位,其结果为 -1。
0000 0000 0000 0000 0000 0000 0000 0001
1000 0000 0000 0000 0000 0000 0000 0000
1111 1111 1111 1111 1111 1111 1111 1111
位逻辑运算符
包括:
& 与;
| 或;
~ 非(也叫做求反);
^ 异或
“& 与”、“| 或”、“~ 非”是基本逻辑运算,由此可以演变出“与非”、“或非”、“与或非”复合逻辑运算。“^ 异或”是一种特殊的逻辑运算,对它求反可以得到“同或”,所以“同或”逻辑也叫“异或非”逻辑。
例子:
5&3=1
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0001
-5&3=1
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0011
5|3=7
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0111
-5|3=-5
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1011
~5=-6
0000 0000 0000 0000 0000 0000 0000 0101
1111 1111 1111 1111 1111 1111 1111 1010
~-5=4
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0100
5^3=6
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0110
-5^3=-8
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1000
转载于:https://www.cnblogs.com/qiengo/archive/2012/05/18/2507715.html
Java Bitwise Operators相关推荐
- Bitwise Operators
Bitwise Operators : NOT, AND and XOR Intuition Now let's discuss O(1)O(1) space solution by using th ...
- kotlin 运算符_Kotlin属性,数据类型,运算符
kotlin 运算符 In this tutorial, we'll be digging deep into the basic fundamental blocks of Kotlin, name ...
- Java中sin、log、tan等复杂数学运算怎么搞?
MXReflection,一个基于mXparser库功能的Java复杂计算框架. 还记不记得求学时代各种复杂的数学公式?sin.log2.tan等等等,是不是看到这就觉得算起来麻烦? 通过MXRefl ...
- Java基础知识总结(一)
<Java基础知识总结>系列是对自己学习Java历程中知识的一个总结,也是为自己找工作前知识的回顾,为找工作奠定基础. 1.Identifiers:标识符 ①Names of class, ...
- java结构设计_Java基本的程序设计结构(一)
前言:虽然说学过设计模式,J2EE,这个学期才开始学Java,呵呵,有点颠倒了,但是还是要从基本的抓起.hoho-- (一)一个简单的java应用程序 Package edu.ynu.java.les ...
- 郑志远的java学习笔记
郑志远的java学习笔记 郑志远 CCB 1 Java起源 略 2 Java语言概述 1.面向对象编程的3个原则:封装(encapsulation).继承(inh ...
- 学习笔记(java)
ztips tips 赛百空间 赛百空间是由计算机和网络组成的一个信息世界,它是对现实世界的高度浓缩与映射.人们进入赛百空间无非是获取信息与提供信息. tips applet(小应用程序) 小应用 程 ...
- Java基础入门|基于美国大学教材
前言 本人陆本经济学转码计算机在读,目前就读于威斯康星麦迪逊大学.基于中美教育的一些不同,特开设此专栏协助学习,也供有需要的有缘人使用. 该专栏会串联琐碎的知识,将它们按照"当一个人正在写程 ...
- Java精炼语言语法描述
学习hadoop---Java初级快速入门指导(2) http://www.aboutyun.com/thread-6921-1-1.html (出处: about云开发) 阅读本文可以带着下面问题: ...
- 老司机也晕车--java字符串String晕车之旅
首先声明,有晕车经历的司机请自备药物,String也可能让你怀疑人生! 第一道 开胃菜 请听题!第一道题: String hello="hello world!";String h ...
最新文章
- java闭合数据_java多线程中线程封闭详解
- 只有当前用户或管理员能登录到此计算机,当前登录的用户没有管理员权限。请重新以管理员身份登录,或与您的pc管理员联系。...
- 流式计算新贵Kafka Stream设计详解--转
- 下一代微服务Service Mesh原理及实践
- 基于tcp的网络程序_【CVPR 2020 Tutorial】基于神经网络的符号化视觉推理和程序合成(2)...
- mongodb数据库显示obj_Mongodb使用
- 左栏固定,右栏自适应
- unity制作预制体,动态加载预制体,实用资源的导出
- 详解 Python 字符串(一):字符串基础
- Unity3D C#数学系列之创建圆柱体
- ANDROID webview解决视频无法播放问题
- 企业微信品牌私域运营案例合集
- Benefits from music
- Springboot2(43)轻松搞定自定义@Enable模块装配
- 老嘤学习笔记 python异常处理
- 想知道立冬南北方的气候差异?
- 包子笔记 - 借贷投资就相当于赌博
- 年薪35w程序员,考上老家公务员,怎么选?网友建议太狠了...
- 阿里P8架构师谈(9):流量高峰时期的性能瓶颈有哪些、以及如何来解决
- 计算机辅助测试技术最近的发展,计算机辅助测试技术演示文稿.PPT