浅析java移位符的具体使用

概述

java移位符主要包括3种:

运算符 名称
>> 左移运算符
<< 有符号右移运算符
<<< 无符号右移运算符

这里我们先附上代码运行实例,原理将在后面以解析下面代码的方式进行讲解:

public class BitOperatorTest {
 public static void main(String[] args){
  System.out.println(1 << 4);
  System.out.println(-1 << 3);
  System.out.println(8 >> 3);
  System.out.println(-8 >> 3);
  System.out.println(-8 >>> 3);
 }
}

结果如下:

16
-8
1
-1
536870911

首先我们需要清楚在计算机系统中,数值一般用补码来表示,主要原因是因为使用补码可以使符号位和其他位统一处理,我们需要将上面的数值都转化为补码。

左移运算符

1 << 4

首先我们将1化为源码:0000 0000 0000 0000 0000 0000 0000 0001 (因为其是int类型,所以化为二进制有32位)

正数的补码和反码等于源码的本身。所以补码也为上述二进制代码。

左移运算符是将操作数的二进制码整理左移指定位数,左移后右面空出的位用0来补充。

左移4位 0000 0000 0000 0000 0000 0000 0000 0001 1*2^0=1

<font color=red>0000</font> 0000 0000 0000 0000 0000 0000 0001 <font color=blue>0000</font> (红色被移除截断,蓝色是新补的0) 1*2^4=16

-1 << 3

我们开始第二个输出语句,这是一个负数。负数的反码是他的源码符号位不变,其余按位取反。补码是他的反码加一。
所以我们可以得到-1的源码为1000 0000 0000 0000 0000 0000 0000 0001 -1*2^0=-1
          反码为1111 1111 1111 1111 1111 1111 1111 1110
          补码为1111 1111 1111 1111 1111 1111 1111 1111

对补码进行操作得<font color=red>111</font> 1111 1111 1111 1111 1111 1111 1111 1<font color=blue>000</font> (红色被移除截断,蓝色是新补的0)

将结果数转化为源码得1000 0000 0000 0000 0000 0000 0000 1000 -1*2^3=-8

总结

所以通过上面对左移运算符的简单使用不难发现,我们可以将其简便理解为移动几位,就是为操作数乘以2的几次方。

右移运算符

左移运算符不牵扯符号位的增补符号位,所以没有有无符号分类

有符号右移运算符

8 >> 3

根据上面流程,我这里直接就简化为
   源码为:0000 0000 0000 0000 0000 0000 0000 1000 1*2^3=8
   反码为:0000 0000 0000 0000 0000 0000 0000 1000
   补码为:0000 0000 0000 0000 0000 0000 0000 1000

运算后结果:<font color=blue>000</font>0 0000 0000 0000 0000 0000 0000 0001 <font color=red>000</font> 1*2^0=1(红色被移除截断,蓝色是新补的符号位,并且以原来的符号位填补)

-8 >> 3

根据上面流程,我这里直接就简化为
   源码为:1000 0000 0000 0000 0000 0000 0000 1000 -1*2^3=8
   反码为:1111 1111 1111 1111 1111 1111 1111 0111
   补码为:1111 1111 1111 1111 1111 1111 1111 1000

运算后结果:<font color=blue>111</font>1 1111 1111 1111 1111 1111 1111 1111 <font color=red>000</font> (红色被移除截断,蓝色是新补的符号位,并且以原来的符号位填补)
转换为源码为:1000 0000 0000 0000 0000 0000 0000 0001 -1*2^0=-1

总结

同左移运算符一样,总结规律后可得出,右移运算符移动几位则是对操作数除以2的多少次方。

无符号右移运算符

-8 >>> 3

根据上面流程,我这里直接就简化为
   源码为:1000 0000 0000 0000 0000 0000 0000 1000 -1*2^3=8
   反码为:1111 1111 1111 1111 1111 1111 1111 0111
   补码为:1111 1111 1111 1111 1111 1111 1111 1000

运算后结果:<font color=yellow>000</font>1 1111 1111 1111 1111 1111 1111 1111 <font color=red>000</font> (红色被移除截断,注意黄色部分,在无符号右移运算位中统一补0)

此时数值将会非常大,所以得到程序中的结果。

补充

如果操作类型低于int类型,比如byte,char等,先将其转化为int类型在进行移位。

对于int类型的移位,如果移动位数超过32位,则让位数对32取余,然后进行运行,即a>>33 == a>>1 a>>32 ==a

同样如果对于long类型的移位,移动位数超过64,则也需要对移动位数进行处理。

代码补充

对于补充内容的代码不进行详解,代码及运算结果如下,基本流程与上面类似,

代码:

public class BitOperatorTest {
 public static void main(String[] args){
  System.out.println((char)4 << 4);
  System.out.println(4 << 4);
  System.out.println(4 << 36);
  System.out.println((long)1214 >> 66);
  System.out.println((long)1214 >> 2);
 }
}

运行结果:

64
64
64
303
303

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java中的位运算符、移位运算详细介绍

    一.位运算 Java中有4个位运算,它们的运算规则如下: (1)按位与 (&) :两位全为1,结果为1,否则为0: (2)按位或 (|) :两位有一个为1,结果为1,否则为0: (3)按位取反(~):0 变 1, 1变0: (4)按位异或(^):两位,如果相同,结果为0:如果不同,结果为1: 注意: (1)位运算中的 符号位(最高位)也跟着变; (2)位运算符与逻辑运算符(逻辑与&&.逻辑或||.逻辑非! )有点相似.但是,逻辑运算符只能操作boolean变量 (也就是左右两边的值

  • Java利用移位运算将int型分解成四个byte型的方法

    package 移位运算; public class 移位运算 { public static void main(String[] args) { //00000111 01011011 11001101 00010101 int n=123456789; //n为需要进行移位处理的32位int型初始值 byte[] a =chai(n); for (int i = 0; i < a.length; i++) { byte b=a[i]; System.out.print(b+" &qu

  • Java中位运算(移位、位与、或、异或、非) 的简单实例

    复制代码 代码如下: public class Test {     public static void main(String[] args) {         // 1.左移( << )         // 0000 0000 0000 0000 0000 0000 0000 0101 然后左移2位后,低位补0://         // 0000 0000 0000 0000 0000 0000 0001 0100 换算成10进制为20         System.out.pri

  • java基于移位操作实现二进制处理的方法示例

    本文实例讲述了java基于移位操作实现二进制处理的方法.分享给大家供大家参考,具体如下: /** * @author openks * @since 2013-9-21 移位操作实例 */ public class TestDisplacement { /** * @param args */ public static void main(String[] args) { // 十进制数字2向左移3位 即 二进制的10向左移3位即10000 转换为十进制为2的4次方 即16 System.ou

  • java中关于移位运算符的demo与总结(推荐)

    首先,移位运算符有三种,其操作类型只支持:byte / short / char / int和long五种. << 左移运算符,表示将左边的操作数的二进制数据向左移动*位,移动后空缺位以0填充,多余位舍弃.(等同于乘2的n次方) >> 右移运算符,二进制数据向右移动*位,就在其二进制数据后抹掉几位?(这里还不错定,但个人理解是这样的)(等同于除2的n次方) >>> 无符号右移运算符,不管移动前最高位是0还是1,右移后左侧产生的空位部分都以0来填充. 下面我们借一个

  • java<<、>>、>>>移位操作方法

    <<,有符号左移位,将运算数的二进制整体左移指定位数,低位用0补齐. int leftShift = 10; System.out.println("十进制:" + leftShift + ", 二进制:" + Integer.toBinaryString(leftShift)); int newLeftShift = letfShift << 2; System.out.println("左移2位后十进制:" + new

  • java中的移位运算符心得总结

    java中有三种移位运算符 <<      :     左移运算符,num << 1,相当于num乘以2 >>      :     右移运算符,num >> 1,相当于num除以2 >>>    :     无符号右移,忽略符号位,空位都以0补齐 下面来看看这些移位运算都是怎样使用的 复制代码 代码如下: /** *  */package com.b510.test; /** * @author Jone Hongten * @creat

  • 浅析java移位符的具体使用

    概述 java移位符主要包括3种: 运算符 名称 >> 左移运算符 << 有符号右移运算符 <<< 无符号右移运算符 这里我们先附上代码运行实例,原理将在后面以解析下面代码的方式进行讲解: public class BitOperatorTest { public static void main(String[] args){ System.out.println(1 << 4); System.out.println(-1 << 3);

  • 浅析java修饰符访问权限(动力节点Java学院整理)

    Java有四种访问权限,其中三种有访问权限修饰符,分别为private,public和protected,还有一种不带任何修饰符: 1. private: Java语言中对访问权限限制的最窄的修饰符,一般称之为"私有的".被其修饰的类.属性以及方法只能被该类的对象访问,其子类不能访问,更不能允许跨包访问. 2. default:即不加任何访问修饰符,通常称为"默认访问模式".该模式下,只允许在同一个包中进行访问. 3. protect: 介于public 和 pri

  • 深入浅析java web log4j 配置及在web项目中配置Log4j的技巧

    在上篇文章给大家介绍了Java log4j详细教程,本文给大家介绍java web log4j配置及web项目中配置log4j的技巧.具体详情请看下文吧. 首先给大家提供log4j.jar下载:http://logging.apache.org/log4j/1.2/download.html 一.java web项目使用log4j 1.在web.xml文件中添加 <!-- 配置log4j --> <context-param> <param-name>webAppRoo

  • 浅析Java内部类——成员内部类

    内部类是什么,简单来说,就是定义在类内部的类(一本正经的说着废话). 一个正经的内部类是长这样的: public class Outer { class Inner{ } } 这是为了演示而写的类,没有什么luan用,可以看到Inner类置于Outer类的内部. 那为什么要大费周章的在类内部定义一个类呢?不能在类外部定义类吗?内部类跟外部类有什么关系? 确实,很多时候,在外部单独定义一个类确实更加方便,也更加通用,但内部类的存在自然有其存在的道理,内部类作为寄生在外部类的类,可以自由访问内部类的

  • 浅析java 的 static 关键字用法

    本篇浅析java中static的用法,主要五个方面:静态成员变量,静态方法,静态块,静态内部类,静态导包. 首先还是一张表格说一下静态对象和非静态对象的区别: 静态对象 非静态对象 归属 类共同具有 类的各个实例独立拥有 内存分配 内存空间上固定的 附属类分配 分配空间顺序 优先分配静态对象空间 优先分配静态对象空间,初始化也一样 1 静态变量,静态方法,静态块 静态对象,静态方法都是在原对象和方法上加上static关键字修饰,表示类可以直接调用这些,而不需要实例化后再调用.具有的好处是: 1-

  • 浅析Java编程中类和对象的定义

    1,什么是类? 答:类是客观存在的,抽象的,概念的东西. 2,什么事对象? 答:对象是具体的,实际的,代表一个事物.例如:车是一个类,汽车,自行车就是他的对象. 关于类与对象的描述:类是对象的模版,对象是类的一个个体. 3,Java中定义类的方法? class 类名 用Java语法定义人类: public class Person { } 4,对象的定义方法? 1,对象声明:类名 对象名: 2,对象创建 对象名 =  new 类名(): new作用:分配内存空间. 也可以合写为:类名 对象名 =

  • 浅析Java类和数据结构中常用的方法

    1.Object类里面常用的方法: protected Object clone()创建并返回此对象的一个副本. boolean equals(Object obj)指示其他某个对象是否与此对象"相等". protected void finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法. Class<?> getClass()返回此 Object 的运行时类. int hashCode()返回该对象的哈希码值. void notif

  • 浅析Java内存模型与垃圾回收

    1.Java内存模型 Java虚拟机在执行程序时把它管理的内存分为若干数据区域,这些数据区域分布情况如下图所示: 程序计数器:一块较小内存区域,指向当前所执行的字节码.如果线程正在执行一个Java方法,这个计数器记录正在执行的虚拟机字节码指令的地址,如果执行的是Native方法,这个计算器值为空. Java虚拟机栈:线程私有的,其生命周期和线程一致,每个方法执行时都会创建一个栈帧用于存储局部变量表.操作数栈.动态链接.方法出口等信息. 本地方法栈:与虚拟机栈功能类似,只不过虚拟机栈为虚拟机执行J

  • 浅析java中stringBuilder的用法

    String对象是不可改变的.每次使用 System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需要对字符串执行重复修改的情况下,与创建新的 String对象相关的系统开销可能会非常昂贵.如果要修改字符串而不创建新的对象,则可以使用System.Text.StringBuilder类.例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder类可以提升性能. 通过用一个重载的构造函数方法初始化变量,可以创建 Strin

  • 浅析Java 常用的 4 种加密方式(MD5+Base64+SHA+BCrypt)

    一.工具类  md5加密工具类  public class MD5Utils { private static final String hexDigIts[] = {"0","1","2","3","4","5","6","7","8","9","a","b",&qu

随机推荐