按位操作符

​ 按位操作符用来操作基本数据类型中的单个“比特”(bit),即二进制位。按位操作符会对两个参数中对应的位执行布尔代数运算,并最终生成一个结果。

​ 我们常用的按位操作符有以下几种:

  • &:与,如果参加运算的两个输入位都是1,则结果为1,否则生成一个输出位0

  • |:或,只要有一个输入位为1,则结果为1。换言之,只有两个输入位为0,结果才为0

  • ~:非,非运算符为一元运算符,只对一个操作符操作,也叫取反运算符

  • ^:异或,只有参加运算的两个输入数相反时,才会输出1

    我们做以下实验:

    public class Main {
    public static void main(String[] args) {
    int a = 16;
    int b = 15;
    String binaryStringA = Integer.toBinaryString(a);
    String binaryStringB = Integer.toBinaryString(b);
    // 填充到32位
    String a32 = StringUtils.leftPad(binaryStringA, 32,"0");
    String b32 = StringUtils.leftPad(binaryStringB, 32,"0");
    System.out.println(a+"的二进制为:"+a32);
    System.out.println(b+"的二进制为:"+b32);
    System.out.println("a&b="+(a&b));
    }
    }

    输出如下:

16的二进制为:00000000000000000000000000010000

15的二进制为:00000000000000000000000000001111

a&b=0


**解释**:这里因为操作数都是int,所以我将其都填充到32,这样更直观,我们可以看到,转换成二进制后,16,15每个bit上的值都是不一样的,所以最终的运算结果为0 ​ 上面我们测试了两个int类型的与操作,不知道大家有没有疑惑,如果参加运算的两个输入数类型不一致会怎么样呢?比如一个为int,另外一个为long呢? ​ 我们来测试下: ```java

​ 结果如下:


我们可以得出结论:

当数据类型不一致时,会自动将低级的数据类型往高级转,在我们上面的例子中,很明显,a被转成了long类型。

我们也可以对编译生成的class文件进行反编译,可以看到如下的代码:

public class Main {
public Main() {
} public static void main(String[] args) {
int a = 16;
long b = 9223372036854775807L;
String binaryStringA = Integer.toBinaryString(a);
String binaryStringB = Long.toBinaryString(b);
String a32 = StringUtils.leftPad(binaryStringA, 32, "0");
String b32 = StringUtils.leftPad(binaryStringB, 64, "0");
System.out.println(a + "的二进制为:" + a32);
System.out.println(b + "的二进制为:" + b32);
System.out.println("a&b=" + ((long)a & b));
}
}

可以看到(long)a & b,在这里编译器自动进行了转换。

或跟异或在这里就不多赘述了,跟与操作差不多。

需要注意的是,非运算符,这是一个一元运算符,也就是说参与运算的只能有一个输入数,所以对于与,或,非,我们可以与赋值运算符“=”一起使用,但是非不行。比如我们可以写成a&=b或者a|=b,但是非是不行的另外对于布尔类型,不能执行非操作

移位操作符

​ 移位操作符操作的运算对象也是二进制的bit位。移位运算符只能用来处理整数类型(基本类型的一种)。左移运算符(<<)能按照操作符右侧指定的位数将操作符左边的数字向左移动(低位自动补0),对于右移这一操作,分为无符号右移(>>>)跟有符号右移(>>),所谓有符号右移是指,在进行运算时,如果原操作符的符号为正,则在高位补0,若为负,则在高位补1。而无符号右移,代表了不论正负,都会在高位补0。

​ 如果对char,byte,short类型的数值进行移位处理,那么在进行操作之前他们会被转成int类型,并且得到的结果也是一个int类型的值。到这里不知道大家会不会有一个疑惑,如果会被转成int类型的话,我们知道int类型的长度为32位(其中一位为符号位),那么如果移位的位数超过32怎么办呢?我们以a>>>n这个表达式为例,n代表移位的位数,实际上更准确的讲,移位的位数=n%32,即n除以32取余。

​ 测试代码如下:

public class Main {
public static void main(String[] args) {
// 32%32=0,所以结果还是8
System.out.println("8>>32=" + (8 >> 32));
// 33%32=1,所以相当于右移一位,其实右移一位,就是除以2,左移一位就是乘以2
// 以此类推,右移n位,相当于除以2的n次方
// 左移n位,相当于乘以2的n次方(在数字没有溢出的前提下结论才成立)
// 这个结论大家可以用画图的方式自己推导下
System.out.println("8>>33=" + (8 >> 33));
}
}

移位操作符与“=”赋值运算符配合使用

在这里我们讨论下<<=,>>=,>>>=这几个运算符。

​ 主要讨论下面这种情况:我们知道对char,byte,short类型的数据进行移位运算时,会将其转换为int类型,那么在这种情况下,对一个byte类型的数据使用>>=,或者>>>=,会怎么样呢?主要就是讨论,如果运算后的结果超过了byte类型的上限怎么办呢?(这里只是以byte为例,对于其他两种类型也是一样的)

​ 测试代码:

public class Main {
public static void main(String[] args) {
byte b = -1;
System.out.println(Integer.toBinaryString(b));
b >>>= 10;
System.out.println(Integer.toBinaryString(b));
System.out.println(Integer.toBinaryString(b>>>10));
}
}

​ 结果如下:

11111111111111111111111111111111
11111111111111111111111111111111
(0000000000)1111111111111111111111

​ 这是因为,在运算过程中,byte类型会先转成int类型,但是当被赋值到一个byte上时,会被截断。在这种情况下就出现了这种诡异的情况(括号中的0是我手动补的)

​ 补充知识:

在计算机中,负数以原码的补码形式表达。
什么叫补码呢?这得从原码,反码说起。 原码:一个正数,按照绝对值大小转换成的二进制数;一个负数按照绝对值大小转换成的二进制数,然后最高位补1,称为原码。
比如 00000000 00000000 00000000 00000101 是 5的 原码;10000000 00000000 00000000 00000101 是 -5的 原码。   反码:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。
取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)
比如:正数00000000 00000000 00000000 00000101 的反码还是 00000000 00000000 00000000 00000101 ;
负数10000000 00000000 00000000 00000101每一位取反(除符号位),得11111111 11111111 11111111 11111010。
称:10000000 00000000 00000000 00000101 和 11111111 11111111 11111111 11111010互为反码。   补码:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.
比如:10000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010。
那么,补码为:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
所以,-5 在计算机中表达为:11111111 11111111 11111111 11111011

java基础篇 之 位运算符的更多相关文章

  1. Java基础——逻辑运算符、位运算符

    逻辑运算符.位运算符.三元运算符 逻辑运算符  public class Demon05 {     public static void main(String[] args) {          ...

  2. 第二十二节:Java语言基础-详细讲解位运算符与流程控制语句

    位运算符(二进制位运算) 运算符 运算 例子 << 左移 3 << 2 = 12 --> 3 * 2 * 2 =12 >> 右移 3 >> 1 = ...

  3. 小白—职场之Java基础篇

    java基础篇 java基础 目录 1.java是一种什么语言,jdk,jre,jvm三者的区别 2.java 1.5之后的三大版本 3.java跨平台及其原理 4.java 语言的特点 5.什么是字 ...

  4. java基础篇1

    JAVA基础篇1 注释 单行注释 //这是一个单行注释,由两个斜杠组成,不能嵌套多行注释 多行注释 /*这是一个 多行注释 ,//里面不能嵌套多行注释, 但是可以嵌套单行注释*/ 文档注释 /**ja ...

  5. 金三银四跳槽季,BAT美团滴滴java面试大纲(带答案版)之一:Java基础篇

    Java基础篇: 题记:本系列文章,会尽量模拟面试现场对话情景, 用口语而非书面语 ,采用问答形式来展现.另外每一个问题都附上“延伸”,这部分内容是帮助小伙伴们更深的理解一些底层细节的补充,在面试中可 ...

  6. java基础篇---HTTP协议

    java基础篇---HTTP协议   HTTP协议一直是自己的薄弱点,也没抽太多时间去看这方面的内容,今天兴致来了就在网上搜了下关于http协议,发现有园友写了一篇非常好的博文,博文地址:(http: ...

  7. Python基础篇(格式化输出,运算符,编码):

    Python基础篇(格式化输出,运算符,编码): 格式化输出: 格式:print ( " 内容%s" %(变量)) 字符类型: %s  替换字符串      %d 替换整体数字  ...

  8. SQL Server调优系列基础篇(联合运算符总结)

    前言 上两篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符的优化技巧,本篇我们总结联合运算符的使用方式和优化技巧. 废话少说,直接进入本篇的主题. 技术准备 基于SQL Server200 ...

  9. java基础篇---I/O技术

    java基础篇---I/O技术   对于任何程序设计语言而言,输入输出(I/O)系统都是比较复杂的而且还是比较核心的.在java.io.包中提供了相关的API. java中流的概念划分 流的方向: 输 ...

随机推荐

  1. Python实战---制作专属有声小说(调用百度语音合成接口)

    这一次的目标是使用百度云的人工智能接口,实现文字转语音的实时转换,将小说文字转换成语音朗读出来. 百度云接口调用 百度的这个接口对于我们普通用户非常友好,他的很多功能都是免费的,而且我们每天可以免费调 ...

  2. 【转】Centos7启动网卡(获取ip地址)

    这里之所以是查看下IP ,是我们后面要建一个Centos远程工具Xshell 连接Centos的时候,需要IP地址,所以我们这里先 学会查看虚拟机里的Centos7的IP地址 首先我们登录操作系统 用 ...

  3. Qt发送一次信号触发两次槽函数的原因

    在手动为控件编写槽函数的时候,如果将槽函数名字按如下格式编辑,则不需要再次进行手动关联 void on_pushButton_1_clicked(); void on_radioButton_clic ...

  4. Daily Scrum 12/24/2015

    Process: Zhaoyang: Some UI change and compile the Caffe in the IOS. Yandong: Do some code integratio ...

  5. Vmware下安装Linux

    Linux系统 开源的操作系统.主要是应用在软件的服务器,性能比windows要好. Linux系统(ubuntu,centos,redhat,aix....) Linux主要是通过命令去操作计算机, ...

  6. G - Pairs Forming LCM LightOJ - 1236 (质因子分解)

    题解:这道题要从n的角度来考虑i和j. n可以表示为n=a1^p1*a2^p2*a3^p3.......n=lcm(i,j),那么质因子a1^p1,a1可以在i或者j中,并且p1=max(a1i,a1 ...

  7. A - Number Sequence 哈希算法(例题)

    Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M ...

  8. reactnavigation 5.x简单例子

    随着RN和reactnavigation的版本更新,网上很多老版的例子都不能用了. 自己摸索着跑通了一些简单的功能. 使用的是最新的    "react-native": &quo ...

  9. [转载]MySQL中int(11)最大长度是多少?

    原文地址:https://blog.csdn.net/allenjay11/article/details/76549503 今天在添加数据的时候,发现当数据类型为 int(11) 时,我当时让用户添 ...

  10. Spark SQL源码解析(二)Antlr4解析Sql并生成树

    Spark SQL原理解析前言: Spark SQL源码剖析(一)SQL解析框架Catalyst流程概述 这一次要开始真正介绍Spark解析SQL的流程,首先是从Sql Parse阶段开始,简单点说, ...