位运算

什么是位运算

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作; CPU支持位运算,位运算操作符(+,-,/,*)效率更高。

我们的位运算其实是通过 补码 进行运算的;先把原码转换成补码,对补码进行计算后,在转换成原码

原码,反码,补码

原码: 是最简单的机器数表示法。用最高位表示符号位,‘1’表示负号,‘0’表示正号。其他位存放该数的二进制的绝对值。

反码:

  • 正数的补码反码是其本身
  • 负数的反码是符号位保持不变,其余位取反

补码:

  • 正数的补码是本身
  • 负数是补码是在它的反码基础上+1

示例: 9 的原码,反码,补码

假如是32位

9 的原码,反码,补码相同:
00000000 00000000 00000000  00001001

示例: -9 的原码,反码,补码

-9的原码:  	10000000 00000000 00000000  00001001
-9的反码: 	11111111 11111111 11111111  11110110
-9的补码:  	11111111 11111111 11111111  11110111    

运算符号

符号描述规则
&按位与位的两个数字都为1,则为1
|按位或位只要一个为1即为1。
^按位异或位不同则该位为1, 否则该位为0
~按位取反按位取反,0变1,1变0。 计算公式:~x=-(x+1);
<<左移各位全部左移n位,低位: 补0
>>带符号右移各位全部右移n位,如果是正数,高位补0;如果是负数,高位补1
>>>无符号右移各位全部右移n位,高位无论正负通通补0,低位: 丢弃

按位与&

定义:参加运算的两个数据,按二进制位进行“与”运算。
运算规则:

0&0=0  0&1=0  1&0=0  1&1=1

示例

int a = 9;  //1001
int b = 12; //1100
System.out.println(a&b);
输出: 8

图解
在这里插入图片描述

示例

     int a = -9;
     int b = 12;
     System.out.println(a&b);
     输出:4

图解
在这里插入图片描述

按位或|

定义:参加运算的两个对象,按二进制位进行“或”运算。
运算规则:

0|0=0  0|1=1  1|0=1  1|1=1

示例

 int a = -9; 
 int b = 12; 
 System.out.println(a|b);
 输出:1

图解
在这里插入图片描述

按位异或^

定义:参加运算的两个数据,按二进制位进行“异或”运算。

运算规则

0^0=0  0^1=1  1^0=1  1^1=0

示例

int a = 9;  //1001
int b = 12; //1100
System.out.println(a^b);
输出:5

图解
在这里插入图片描述

按位取反~

定义:参加运算的一个数据,按二进制进行“取反”运算。

示例

  int a = 9;  //1001
  System.out.println(~a);
  输出: -10

图解
在这里插入图片描述
当然: 你可以根据公式:~x=-(x+1)来计算; -(9+1)=-10。
实例

int a = -9;  //1001
System.out.println(~a);
输出:8

图解
在这里插入图片描述

公式: -( -9+1)= 8

左移<<

各位全部左移n位,低位:补0

实例

 int a = 9<<2;  //1001
System.out.println(a);

图解
在这里插入图片描述

带符号右移>>

运算规则:各位右移n位,符号位为正,高位补零,符号位负高位补一,低位直接移除。

示例

 int a = 9>>2;  //1001
 System.out.println(a);
 结果: 2

图解
在这里插入图片描述
示例

   int a = -9>>2;
   System.out.println(a);
   输出:-3

图解
在这里插入图片描述

无符号右移>>>

无符号右移。无论正数还是负数,高位通通补0.

为什么要使用位运算?

位运算可以提高运算效率,还可以设计巧妙的算法。

如在hashmap就用了挺多位运算

//默认初始化容量 1 << 4 =16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
//    默认最大容量
static final int MAXIMUM_CAPACITY = 1 << 30;
	
//计算hash,让高16为也参与运算
 static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

//寻址算法
p = tab[i = (n - 1) & hash]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值