前天几天研究了下JDK的Collection接口,本来准备接着研究Map接口,可是一查看HashMap类源码傻眼咯,到处是位运算实现,所以我觉得还是有必要先补补位运算知识,不然代码看起来有点费力。今天系统研究了下,现记录如下。

首先要明白一个概念,Java位运算是针对于整型数据类型的二进制进行的移位操作。主要包括位与、位或、位非,有符号左移、有符号右移,无符号右移等等。需要注意一点的是,不存在无符号左移<<<运算符。根据位运算的概念规定,我们首先需要弄明白两个问题,java有哪些数据类型是整型数据类型和各数字进制之间转换问题。Java整型数据类型有:byte、char、short、int、long。要把它们转换成二进制的原码形式,必须明白他们各占几个字节。我们都知道,一个字节占8位。
      数据类型                           所占位数
      byte                                       8 
      boolean                                8
      short                                    16
      int                                         32 
      long                                      64 
      float                                      32 
      double                                  64 
      char                                     16

还需要明白一点的是:计算机表示数字正负不是用+ -加减号来表示,而是用最高位数字来表示,0表示正,1表示负

所以比如-4用二进制原码表示就是1111 1111 1111 1111 1111 1111 1111 1100

下面根据实例一个一个的来说明各种位运算的运算规则:
位与&(真真为真 真假为假 假假为假)
4&6
0000 0000 0000 0000 0000 0000 0000 0100
0000 0000 0000 0000 0000 0000 0000 0110
0000 0000 0000 0000 0000 0000 0000 0100
结果:4

位或|(真真为真 真假为真 假假为假)
4|6
0000 0000 0000 0000 0000 0000 0000 0100
0000 0000 0000 0000 0000 0000 0000 0110
0000 0000 0000 0000 0000 0000 0000 0110
结果:6

位非~(取反码)【注:Java中正数的最高位为0,负数最高位为1,即最高位决定正负符号】
~4
0000 0000 0000 0000 0000 0000 0000 0100
1111 1111 1111 1111 1111 1111 1111 1011

解码:先取反码,再补码
0000 0000 0000 0000 0000 0000 0000 0100
0000 0000 0000 0000 0000 0000 0000 0101
结果:-5

位异或^(真真为假 真假为真 假假为假)
4^6
0000 0000 0000 0000 0000 0000 0000 0100
0000 0000 0000 0000 0000 0000 0000 0110
0000 0000 0000 0000 0000 0000 0000 0010
结果:2

有符号右移>>(若正数,高位补0,负数,高位补1)
-4>>2
1111 1111 1111 1111 1111 1111 1111 1100   原码
1111 1111 1111 1111 1111 1111 1111 1111   右移,最左边空出两位按规则负数空位补1
0000 0000 0000 0000 0000 0000 0000 0000   解码
0000 0000 0000 0000 0000 0000 0000 0001   补码(补码即最后一位+1)
结果:-1

有符号左移<<(若正数,高位补0,负数,高位补1)
-4<<2
1111 1111 1111 1111 1111 1111 1111 1100   原码
1111 1111 1111 1111 1111 1111 1111 0000   左移,最右边空出两位补0
0000 0000 0000 0000 0000 0000 0000 1111   解码
0000 0000 0000 0000 0000 0000 0001 0000   补码
结果:-16

无符号右移>>>(不论正负,高位均补0)
-4>>>2
1111 1111 1111 1111 1111 1111 1111 1100   原码
0011 1111 1111 1111 1111 1111 1111 1111   右移(由于高位均补0,故>>>后的结果一定是正数)
结果:1073741823

由于数据类型所占字节是有限的,而位移的大小却可以任意大小,所以可能存在位移后超过了该数据类型的表示范围,于是有了这样的规定:
如果为int数据类型,且位移位数大于32位,则首先把位移位数对32取模,不然位移超过总位数没意义的。所以4>>32与4>>0是等价的。

如果为long类型,且位移位数大于64位,则首先把位移位数对64取模,若没超过64位则不用对位数取模。

如果为byte、char、short,则会首先将他们扩充到32位,然后的规则就按照int类型来处理。

学到这里,我想你也可能会问,位运算到底有什么用途或者有哪些场景可以应用到它。因为位运算的运算效率比直接对数字进行加减乘除高很多,所以当出现以下情景且对运算效率要求较高时,可以考虑使用位运算。不过实际工作中,很少用到它,我也不知道为什么很少有人用它,我想应该是它比较晦涩难懂,如果用它来进行一些运算,估计编写的代码的可读性会不强,毕竟我们写的代码不仅仅留给自己一个人看。
1.  判断int型变量a是奇数还是偶数    
     a&1  = 0 偶数 
     a&1 =  1 奇数 
2.  求平均值,比如有两个int类型变量x、y,首先要求x+y的和,再除以2,但是有可能x+y的结果会超过int的最大表示范围,所以位运算就派上用场啦。
      (x&y)+((x^y)>>1); 
3.  对于一个大于0的整数,判断它是不是2的几次方
    ((x&(x-1))==0)&&(x!=0); 
4.  比如有两个int类型变量x、y,要求两者数字交换,位运算的实现方法:性能绝对高效
    x ^= y; 
    y ^= x; 
    x ^= y; 
5. 求绝对值
    int abs( int x ) 
   { 
     int y ; 
     y = x >> 31 ; 
    return (x^y)-y ;        //or: (x+y)^y 
   }
6.  取模运算,采用位运算实现:
     a % (2^n) 等价于 a & (2^n - 1) 
7.  乘法运算   采用位运算实现
     a * (2^n) 等价于 a << n
8.   除法运算转化成位运算
      a / (2^n) 等价于 a>> n 
9.   求相反数
      (~x+1) 
10  a % 2 等价于 a & 1 
等等

当然还有牛人使用位运算来实现权限控制,加密技术,里面的奥秘深不可测

来源:http://www.52ij.com/jishu/102.html

Java位运算总结:位运算用途广泛相关推荐

  1. Java从入门到精通08-二进制、位运算、移位运算

    Java从入门到精通08-二进制.位运算.移位运算 二进制(Binary)数用0和1两个数字及其组合来表示任何数.进位规则是"逢2进1",数字1在不同的位上代表不同的值,按从右到左 ...

  2. java反码算术运算求和,位运算的妙用,运算妙用

    位运算的妙用,运算妙用 最近在学java,其实仅仅是在命令行里写程序跟C语言没有太大的区别,思想都是一样的.遇到了一个比较新鲜(后来知道原来C中也有)的东西--位元算(又叫位操作).多新鲜啊,毕向东老 ...

  3. Java中的位运算符、移位运算

    一.位运算 Java中有4个位运算,它们的运算规则如下: (1)按位与 (&)  :两位全为1,结果为1,否则为0: (2)按位或  (|)   :两位有一个为1,结果为1,否则为0: (3) ...

  4. java中整形_java中怎样实现60多位整形数字的运算

    java中怎样实现60多位整形数字的运算 (2011-09-20 10:57:59) 标签: 杂谈 import java.math.BigInteger; import java.util.Scan ...

  5. java位运算符和位运算表达式

    java位运算符和位运算表达式 > 右移 x>>a X各比特位右移a位 << 左移 X< >> 不带符号的右移 x>>>a X各比特位 ...

  6. java加减_Java位运算实现加减乘除

    一.加法 a+b 举例实现:13+9=22 13+9不考虑进位结果为12 只考虑进位结果为10 和刚好是22. 13二进制为1101,9二进制为1001. 不考虑进位结果为0100.算式为a^b 只考 ...

  7. java取余位运算_java位运算

    位移动运算符: < 例如:3 <<2(3为int型) 1)把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011, 2)把该数字高位(左侧 ...

  8. Java位运算之移位运算

    文章目录 移位运算 左移 << 位运算符 右移 >> 位运算符 无符号右移 >>> 运算符 移位运算 移位运算符在程序设计中,是位操作运算符的一种.移位运算符 ...

  9. 彻底搞清楚Java的位运算(位实现加减乘除)

    目录 •写在前面 •机器数和机器数的真值 •原码.反码和补码的基础概念和计算方法 原码 反码 补码 •java中的运算符 •不用乘除算乘除 加法 减法 乘法 除法 •写在前面 二进制位运算是最贴近计算 ...

  10. Java整形位运算避免精度缺失,中国大学MOOC: 在Java语句中,位运算操作数只能为整型或______数据。...

    中国大学MOOC: 在Java语句中,位运算操作数只能为整型或______数据. 答:字符型 YEAR(date)函数返回值的数据类型是 答:int 青色食物应 木,红色食物应 火,黄色食物应 土,白 ...

最新文章

  1. angular2 step by step #1 - environment setup
  2. 微信小程序教学第二章(含视频):小程序中级实战教程之预备篇 - 封装网络请求及 mock 数据...
  3. 网站外链如何发布才能更快的得到高排名呢?
  4. 从源码透析gRPC调用原理
  5. MySQL存储过程使用游标循环数据列表
  6. windows远程桌面mstsc使用 代理
  7. 阿里云产品头条(2018年1月刊)
  8. Linux驱动学习2
  9. 《深入理解Java虚拟机》读书笔记二
  10. js中动态载入css js样式
  11. 【语音分离】基于matlab FASTICA语音分离【含Matlab源码 1023期】
  12. 使用 Python 进行科学计算 使用 Python 进行科学计算
  13. MIUI目前为止最简单安装谷歌服务框架教程
  14. Jmeter接口测试工具安装
  15. 现钞和现汇有什么区别??
  16. test English
  17. 邮箱发信数量被限制了,有什么方法可以解决么?
  18. Github 之 本地上传代码到 Github ,并且添加 .gitignore 文件 屏蔽一些文件上传(内附详细步骤)
  19. 程序员带你回味童年,一起用C语言做一个“推箱子”玩!【文末源码】
  20. 已知二叉树先序序列和中序序列,求后序序列

热门文章

  1. 从月薪2300块的女工,到年薪80万的程序员:那些习惯“随大流”的人,后来都怎么样了?...
  2. Joost行不行?Joost模式在中国行不行?
  3. SharePoint 2013 OWA(Office Web Apps) 连接与配置
  4. IE8有淘宝定制版,火狐也出了个淘宝专版浏览器。喜欢火狐的试试吧。
  5. /kylin/bin/set-java-home.sh: 第 32 行:[: : 期待整数表达式 kylin/bin/find-hadoop-conf-dir.sh:行33: hbase: 未找到命令
  6. 用access建立一个试题库_access理论考试题库(答案版)
  7. 收到骗子的短信后......
  8. SQLServer 数据库 视图实验练习
  9. 从pdf文件中获取上市公司行业分类
  10. CheckStyle 编写自己的代码检查插件