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中的位运算符、移位运算符的更多相关文章

  1. Java中的位掩码BitMask

    目录 JDK源码的使用 日常工作中的使用 JDK源码的使用 最近在JDK源码中闲逛,无意中看到了java.lang.reflect.Modifier这个类,这个类很简单,都是些常量定义和判断方法,于是 ...

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

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

  3. Java中的位运算符

    Java提供的位运算符有:左移( << ).右移( >> ) .无符号右移( >>> ) .位与( & ) .位或( | ).位非( ~ ).位异或( ...

  4. Java中的位运算符 &、|、^、~、<< 和 >>

    一.& 按位与运算符 5 & 3 = 1 5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101 3转换为二进制:0000 0000 0000 ...

  5. java中的位运算及移位运算

    为了方便对二进制位进行操作,Java给我们提供了以下四个二进制位操作符: &    按位与 |     按位或 ^    按位异或 ~    按位取反 Java中有三个移位运算符: 左移:&l ...

  6. java中的7个位运算运算符

    位运算指的是针对整数的二进制进行的位移操作. 位运算提供比算术运算更高的效率,但是位运算的代码可读性较差,建议所有使用位运算的地方写上注释. Java中提供7个位运算符用于位运算. 左移(<&l ...

  7. java中的、标识符、运算符以及数据类型之间的转换。

    ---恢复内容开始--- 数据类型之间的转换: 1:自动转换:就是不用说出要转换成什么类型,由java中的虚拟机自动将小数据类型转换成大数据类型,但大数据中的数据精度有可能被破坏. 2:强制转换:强制 ...

  8. Java中关于位运算的面试题

    位运算的效率是最高的,因为位位运算是直接对二进制进行操作 位运算只能应用于整型和char类型(char类型可以看做是特殊的无符号的整形) 面试题: a: 判断一个数是否是奇数 a & 1 == ...

  9. Java中的位运算及简单的算法应用介绍

    众所周知,计算机底层是二进制.而java作为一门计算机编程语言,也对二进制的位运算提供了完整的支持. 在java中,int是32位的,也就是说可以用来实现32位的位运算.方便起见,我们一般用16进制对 ...

  10. JAVA中自增自减运算符(i++与++i的区别)

    注意: 自增运算符和自减运算符只能用于变量,而不能用于常亮或表达式 运算符 运算 范例 结果 ++ 自增(前):先运算后取值 a=2;b=++a; a=3;b=3; ++ 自增(后):先取值后运算 a ...

随机推荐

  1. FLink自定义Sink,生产的数据导出到mysql

    一.自定义生产数据 https://www.cnblogs.com/robots2/p/16048729.html 二.生产转化数据,导出到mysql 2.1 建表语句 CREATE TABLE `v ...

  2. .Net Core3.1 集成Log4net

    1.准备 首先nuget添加下引用  Microsoft.Extensions.Logging.Log4Net.AspNetCore 目前的版本为v3.1.0 ,添加完成后我们开始注册. 2.注册 2 ...

  3. P9869 [NOIP2023] 三值逻辑 题解

    NOIP2023 T2 三值逻辑 题解 题面 思路 乍一看好像很并查集,而且不太难,但是, 注意到:按顺序运行这 \(m\) 条语句 事情并没有那么简单. 比如说如下情况: x1:=T x2:=x1 ...

  4. flutter-超出部分隐藏

    第一种写法 1 ConstrainedBox( 2 constraints: BoxConstraints( 3 maxHeight: 100 4 ), 5 child: Stack( 6 overf ...

  5. DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?

    2025年伊始,Meta创始人扎克伯格的一则声明引发全球程序员热议:"AI将在今年达到中级工程师水平,逐步接管编程工作."与此同时,国产AI大模型DeepSeek的爆火,让一名8岁 ...

  6. MONGODB数据备份与导入

    主要记录下在mongo 3.0的操作 备份示例 ./mongodump -h localhost -d liongo -o ./ 还原示例 错误方式: ./mongorestore -h 127.0. ...

  7. mysql连接出现java.sql.sql exception:服务器时区值'''_''''无法识别或表示多个时区

    在连接mysql的JDBC的url后面加上服务器的时区:serverTimezone=UTCjdbc:mysql://localhost:3306/geek?useUnicode=true&c ...

  8. Vigenere密码无密钥求解

    0.前言 最近摸了很长时间的鱼,然后最近突然想搞一个Vigenere密码的自动求解,花了不到一天来实现了一下这个东西,不过受限于自己的水平,没有搞的太难.当然,代码部分不是全部都是从 0 开始的,关于 ...

  9. ISCSI数据盘的多路径配置

    本文分享自天翼云开发者社区<ISCSI数据盘的多路径配置>,作者:w****n 多路径出现的背景 多路径,就是说,主机到存储可以有多条路径可以选择.主机到存储之间的IO由多条路径可以选择. ...

  10. 【Abaqus】*Solid Section定义复合材料

    *SOLID SECTION 介绍 *solid section 用来定义单元的材料属性,材料方向等信息: solid (continuum) elements infinite elements a ...