Java中的位运算符、移位运算符
1 概述
Java中的位运算符有:&(与)、|(或)、^(异或)、~(取反)。
移位运算符有:<<(左移)、>>(右移)、>>>(无符号右移),没有<<<运算符。
2 位运算符
计算口诀
| 运算 | 规则 |
|---|---|
| & | 全1为1 |
| | | 有1为1 |
| ^ | 相异为1 |
| ~ | 全部取反 |
2.1 $(与)
有0为0,全1为1

2.2 |(或)
有1为1,全0为0

2.3 ^(异或)
相同为0,相异为1

2.4 ~(非)
0变1,1变0

3 移位运算
在阅读源码的过程中,经常会看到这些符号<< ,>>,>>>,这些符号在Java中叫移位运算符,在写代码的过程中,虽然我们基本上不会去写这些符号,但需要明白这些符号的运算原理,比如HashMap中有以下代码:
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//1左移4位为16
static final int MAXIMUM_CAPACITY = 1 << 30;//1左移30位为1073741824
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);//无符号右移
}
上段代码中就包含左移运算符<<,无符号右移运算符>>>。
接下来我们以Java中的int类型为例介绍三种移位运算符。
首先定义int类型的变量a,b
int a = 0B00101100_01010011_01101000_11010110; //十进制743663830
int b = 0B10101100_01010011_01101000_11010110; //十进制-1403819818

3.1 左移运算符:<<
左移运算符<<的操作是舍弃高位,低位补0.
如图是int类型a在左移1位和2位后的结果。

可以看到左移1位的值是原始值的两倍,所以可以用左移代理乘2的倍数运算。但是如果左移后的值超出了类型的最大值,结果就不可预知了,可能会变成负数,也可能比原来的值小。如图,变量a在左移两位后最高位变为了1,值就变为了负值。
程序中的写法:
public class TestDemo {
public static void main(String[] args) {
int b = 0B10101100_01010011_01101000_11010110;
int a = 0B00101100_01010011_01101000_11010110;
System.out.println("a的原始十进制:\t"+a);
System.out.println("a的原始二进制:\t"+getBinaryString(a));
System.out.println("a的左移1位二进制:\t"+getBinaryString(a<<1));
System.out.println("a的左移1位十进制:\t"+getInt(getBinaryString(a<<1)));
System.out.println("a的左移2位二进制:\t"+getBinaryString(a<<2));
System.out.println("a的左移2位十进制:\t"+getInt(getBinaryString(a<<2)));
}
static String getBinaryString(int a){
String binaryString = Integer.toBinaryString(a);//转成二进制
String zeroString = "";//补缺少的0
for (int i=0;i<32 - binaryString.length();i++){
zeroString += "0";
}
binaryString = zeroString + binaryString; //补上0的二进制
String regex = "(.{8})";
binaryString = binaryString.replaceAll(regex,"$1_");
binaryString = binaryString.substring(0,binaryString.length() - 1);
return binaryString;
}
static int getInt(String a ){
a = a.replace("_","");
char first = a.charAt(0);
a = a.substring(1);
int value = Integer.parseInt(a,2);
return first == '0' ? value:-value;
}
}
a的原始十进制: 743663830
a的原始二进制: 00101100_01010011_01101000_11010110
a的左移1位二进制:01011000_10100110_11010001_10101100
a的左移1位十进制:1487327660
a的左移2位二进制:10110001_01001101_10100011_01011000
a的左移2位十进制:-827171672
如果移动的位数大于等于类型本身的位数,会对移动的位数求余后再移动。
如 a<<40,是左移40位,大于int类型的32位,实际应该左移40%32=8位。
System.out.println("a左移8位:\t"+(a<<8));
System.out.println("a左移40位:\t"+(a<<40));
a左移8位: 1399379456
a左移40位: 1399379456
可以看到左移8位和左移40位,结果是相同的。
由于double,float在二进制中的表现比较特殊,因此不能来进行移位操作,报错,编译不过,如下图:

注意:其它几种整形byte,short移位前会先转换为int类型(32位)再进行移位,这里就不写代码测试了,大家有兴趣可自行测试。
3.2 右移运算符:>>
左移运算符>>的操作是舍弃低位,高位补符号位.
如图是int类型a在右移1位和2位后的结果。

可以看到右移1位的值是原始值的1/2,所以可以用右移代替除2运算。和左移一样,int类型移位大于等于32位时,long类型大于等于64位时,会先做求余处理再位移处理,byte,short移位前会先转换为int类型(32位)再进行移位。以上是正数的位移,我们再来看看负数的右移运算,如图,


综上所述:右移运算符>>的运算规则也很简单,丢弃右边指定位数,左边补上符号位。
3.3 无符号右移运算符:>>>
无符号右移运算符>>>和右移运算符>>是一样的,只不过右移时左边是补上符号位,而无符号右移运算符是补上0,也就是说,对于正数移位来说等同于:>>,负数通过此移位运算符能移位成正数。


无符号右移运算符>>的运算规则也很简单,丢弃右边指定位数,左边补上0。
参考:Java中的移位运算符
Java中的位运算符、移位运算符的更多相关文章
- Java中的位掩码BitMask
目录 JDK源码的使用 日常工作中的使用 JDK源码的使用 最近在JDK源码中闲逛,无意中看到了java.lang.reflect.Modifier这个类,这个类很简单,都是些常量定义和判断方法,于是 ...
- Java中的位运算符、移位运算
一.位运算 Java中有4个位运算,它们的运算规则如下: (1)按位与 (&) :两位全为1,结果为1,否则为0: (2)按位或 (|) :两位有一个为1,结果为1,否则为0: (3) ...
- Java中的位运算符
Java提供的位运算符有:左移( << ).右移( >> ) .无符号右移( >>> ) .位与( & ) .位或( | ).位非( ~ ).位异或( ...
- Java中的位运算符 &、|、^、~、<< 和 >>
一.& 按位与运算符 5 & 3 = 1 5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101 3转换为二进制:0000 0000 0000 ...
- java中的位运算及移位运算
为了方便对二进制位进行操作,Java给我们提供了以下四个二进制位操作符: & 按位与 | 按位或 ^ 按位异或 ~ 按位取反 Java中有三个移位运算符: 左移:&l ...
- java中的7个位运算运算符
位运算指的是针对整数的二进制进行的位移操作. 位运算提供比算术运算更高的效率,但是位运算的代码可读性较差,建议所有使用位运算的地方写上注释. Java中提供7个位运算符用于位运算. 左移(<&l ...
- java中的、标识符、运算符以及数据类型之间的转换。
---恢复内容开始--- 数据类型之间的转换: 1:自动转换:就是不用说出要转换成什么类型,由java中的虚拟机自动将小数据类型转换成大数据类型,但大数据中的数据精度有可能被破坏. 2:强制转换:强制 ...
- Java中关于位运算的面试题
位运算的效率是最高的,因为位位运算是直接对二进制进行操作 位运算只能应用于整型和char类型(char类型可以看做是特殊的无符号的整形) 面试题: a: 判断一个数是否是奇数 a & 1 == ...
- Java中的位运算及简单的算法应用介绍
众所周知,计算机底层是二进制.而java作为一门计算机编程语言,也对二进制的位运算提供了完整的支持. 在java中,int是32位的,也就是说可以用来实现32位的位运算.方便起见,我们一般用16进制对 ...
- JAVA中自增自减运算符(i++与++i的区别)
注意: 自增运算符和自减运算符只能用于变量,而不能用于常亮或表达式 运算符 运算 范例 结果 ++ 自增(前):先运算后取值 a=2;b=++a; a=3;b=3; ++ 自增(后):先取值后运算 a ...
随机推荐
- FLink自定义Sink,生产的数据导出到mysql
一.自定义生产数据 https://www.cnblogs.com/robots2/p/16048729.html 二.生产转化数据,导出到mysql 2.1 建表语句 CREATE TABLE `v ...
- .Net Core3.1 集成Log4net
1.准备 首先nuget添加下引用 Microsoft.Extensions.Logging.Log4Net.AspNetCore 目前的版本为v3.1.0 ,添加完成后我们开始注册. 2.注册 2 ...
- P9869 [NOIP2023] 三值逻辑 题解
NOIP2023 T2 三值逻辑 题解 题面 思路 乍一看好像很并查集,而且不太难,但是, 注意到:按顺序运行这 \(m\) 条语句 事情并没有那么简单. 比如说如下情况: x1:=T x2:=x1 ...
- flutter-超出部分隐藏
第一种写法 1 ConstrainedBox( 2 constraints: BoxConstraints( 3 maxHeight: 100 4 ), 5 child: Stack( 6 overf ...
- DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
2025年伊始,Meta创始人扎克伯格的一则声明引发全球程序员热议:"AI将在今年达到中级工程师水平,逐步接管编程工作."与此同时,国产AI大模型DeepSeek的爆火,让一名8岁 ...
- MONGODB数据备份与导入
主要记录下在mongo 3.0的操作 备份示例 ./mongodump -h localhost -d liongo -o ./ 还原示例 错误方式: ./mongorestore -h 127.0. ...
- mysql连接出现java.sql.sql exception:服务器时区值'''_''''无法识别或表示多个时区
在连接mysql的JDBC的url后面加上服务器的时区:serverTimezone=UTCjdbc:mysql://localhost:3306/geek?useUnicode=true&c ...
- Vigenere密码无密钥求解
0.前言 最近摸了很长时间的鱼,然后最近突然想搞一个Vigenere密码的自动求解,花了不到一天来实现了一下这个东西,不过受限于自己的水平,没有搞的太难.当然,代码部分不是全部都是从 0 开始的,关于 ...
- ISCSI数据盘的多路径配置
本文分享自天翼云开发者社区<ISCSI数据盘的多路径配置>,作者:w****n 多路径出现的背景 多路径,就是说,主机到存储可以有多条路径可以选择.主机到存储之间的IO由多条路径可以选择. ...
- 【Abaqus】*Solid Section定义复合材料
*SOLID SECTION 介绍 *solid section 用来定义单元的材料属性,材料方向等信息: solid (continuum) elements infinite elements a ...