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. 使用Docker编译安装运行Doris

    一.编译源码 (1)拉取编译镜像docker pull apache/incubator-doris:build-env-1.2 (2)Mac电脑上拉取源码git clone https://gith ...

  2. Luogu P4287 SHOI2011 双倍回文 题解 [ 紫 ] [ manacher ]

    双倍回文:回文子串结论的经典应用. 结论 先放本题最关键的结论:一个字符串本质不同的回文子串最多只有 \(n\) 个. 考虑如何证明: 假设我们一个一个地在当前字符串(黑色部分)的结尾加入字符(红色部 ...

  3. 解密prompt系列49. 回顾R1之前的思维链发展路线

    在所有人都在谈论R1的今天,作为算法也是有些千头万绪无从抓起.所以这一章先复盘,我先按照自己的思路来梳理下R1之前整个模型思维链的发展过程.下一章再展望主要去看RL在Agent上的一些尝试,毕竟Age ...

  4. SpringBoot - [07] Web入门

    题记部分 一.Web 入门   SpringBoot将传统Web开发的mvc.json.tomcat等框架整合,提供了spring-boot-starter-web组件,简化了Web应用配置.创建Sp ...

  5. faker 函数支持哪些

    3.2 常用函数 除了上述介绍的fake.name和fake.address生成姓名和地址两个函数外,常用的faker函数按类别划分有如下一些常用方法. 1.地理信息类 fake.city_suffi ...

  6. nginx 根据 URL 参数引入不同的文件

    同步发布:https://blog.jijian.link/2020-06-30/nginx-import-file/ 编程世界中各种奇奇怪怪的需求都有,本次遇到一个需求:根据URL参数判断,包含 x ...

  7. Django实战项目-学习任务系统-用户管理

    接着上期代码框架,开发第6个功能,用户管理,查看用户信息和学生用户属性值,尤其是总积分值,还可以查看积分流水明细,完成任务奖励积分,兑换物品消耗积分. 第一步:编写第6个功能-用户管理 1,编辑模型文 ...

  8. 系统自带模版在 emlog pro 1.8.0 底部信息错位问题暂时的解决方案

    问题描述 作为一名 emlog 爱好者,笔者闲暇时间经常为 emlog 系统的 Github 仓库里( https://github.com/emlog/emlog )提 pr 和修修补补,就像其他知 ...

  9. 物理机Jenkins接入K8s环境

    前言 本次记录物理机部署Jenkins,k8s弹性伸缩agent节点供部署项目. 安装 K8S 插件 登录 Jenkins,系统管理→ 插件管理 → 搜索 kubernetes,选择第二个 Kuber ...

  10. ASP.NET Session 清除

    // 值为 null,这样对应的 Session 会继续存在,但值为 null Session["UserId"] = null; // 移除指定 Session Session. ...