文档章节

java的移位操作详解,左移和右移

HelloRookie
 HelloRookie
发布于 2017/02/06 17:41
字数 2066
阅读 345
收藏 0

首先要明白一点,这里面所有的操作都是针对存储在计算机中中二进制的操作,那么就要知道,正数在计算机中是用二进制表示的,负数在计算机中使用补码表示的。

左移位:<<,有符号的移位操作
左移操作时将运算数的二进制码整体左移指定位数,左移之后的空位用0补充


右移位:>>,有符号的移位操作
右移操作是将运算数的二进制码整体右移指定位数,右移之后的空位用符号位补充,如果是正数用0补充,负数用1补充。

例子:

public static void main(String[] args)
{

System.out.println(3<<2);//3左移2位
System.out.println(-3<<2);//-3左移2位

System.out.println(6>>2);//6右移2位
System.out.println(-6>>2);//-6右移2位

}

输出结果

12
-12
1
-2
下面解释一下:

00000000 00000000 00000000 00000011 +3在计算机中表示
000000 00000000 00000000 0000001100 左移2位,补0,结果为12

----------------------------------------------------------------------------------------------

00000000 00000000 00000000 00000011 +3在计算机中表示
11111111 11111111 11111111 11111100
11111111 11111111 11111111 11111101 -3在计算机中表示
111111 11111111 11111111 1111110100 左移2位,补0,结果为负数,就是补码了,求原码
10000000 00000000 00000000 00001011
10000000 00000000 00000000 00001100 结果-12
----------------------------------------------------------------------------------------------

这也说明了一个问题:在计算机中,以1开头的就是补码的形式,是负数。

    00000000 00000000 00000000 00000110 +6在计算机中表示方法
0000000000 00000000 00000000 00000110 右移两位,正数补0,结果为1
----------------------------------------------------------------------------------------------

00000000 00000000 00000000 00000110 +6在计算机中表示方法
11111111 11111111 11111111 11111001
11111111 11111111 11111111 11111010 -6在计算机中的表示
11111111 11111111 11111111 11111010 右移两位,结果为负数
1000000000 00000000 00000000 000001
1000000000 00000000 00000000 000010 结果为-2
这个地方很容易弄混,多想几次就会慢慢理解了。

上面解释了带符号的移位操作,下面解释一下不带符号的移位操作

无符号的移位只有右移,没有左移使用“>>>”进行移位,都补充0

例如:
public static void main(String[] args)
{
System.out.println(6>>>2);
System.out.println(-6>>>2);

}
结果:

1
1073741822

分析:

00000000 00000000 00000000 00000110 +6在计算机中表示方法
00000000 00000000 00000000 00000110 右移两位,正数补0,结果为1
-----------------------------------------------------------------------------------------------------

00000000 00000000 00000000 00000110 +6在计算机中表示方法
11111111 11111111 11111111 11111001
11111111 11111111 11111111 11111010 -6在计算机中的表示
0011111111 11111111 11111111 111110 右移两位,补充0,结果为1073741822

 

以下来自:http://jefflee.javaeye.com/blog/203863

可以参考

移位操作要注意的问题是高(低)位是补0还是补1和对char, byte, short型的操作:
(1)<< : (left-shift), 最低位补0
(2)>> : (signed right-shift), 右移过程使用符号位扩展(sign extension),即如果符号为为1则高位补1, 是0则补0,也就是逻辑右移
(3)>>> : (unsigned right-shit),右移过程使用零扩展(zero extension),即最高位一律补0,也就是算术右移
(4)移位操作的数据类型可以是byte, char, short, int, long型,但是对byte, char, short进行操作时会先把它们变成一个int型,最后得到一个int型的结果,对long型操作时得到一个long型结果,不可以对boolean型进行操作。
(5)移位操作符可以和=合并起来,即 <<= 、 >>= 和 >>>=。例如 a >>= 2; 表示将a右移两位后的值重新赋给a。当时在使用这三个操作符对 byte, char, short型数据进行操作时要注意,例如有一下代码片段:

public class ShiftTest
{
public static void main(String [] args)
{
byte a;
byte b;
byte c;
a = 127;
b = 127;
c = 127;
a <<= 2;
System.out.println(a);
System.out.println(b <<= 2);
System.out.println(c << 2);
}
}

运行结果是:
-4
-4
508
这说明了在操作a <<= 2 执行过程是这样的:先将 byte型的数 127变成int型,左移2位得到 508,然后把508赋给byte型变量a时只是简单地"折断"(truncate)得到数-4。编译时编译器不会提示你可能损失精度(实际上在本例中确实是损失精度了),但是如果你把a <<= 2改成 a = a << 2;编译器就会提示可能损失精度了。

 

================================================================================

移位操作的简单计算方法

>>右移操作

x>>y

就是x除以2的y此方,取整数

<<左移操作

X<<y

就是x乘以2的y次方

 

 

 

 

二进制、位运算、位移运算

思考题

1、请看下面的代码段,回答a,b,c,d,e结果是多少?

public static void main(String []args){

int a=1>>2;

int b=-1>>2;

int c=1<<2;

int d=-1<<2;

int e=3>>>2;

//a,b,c,d,e结果是多少

System.out.println("a="+a);//a=0

System.out.println("b="+b);//b=-1

System.out.println("c="+c);//c=4

System.out.println("d="+d);//d=-4

System.out.println("e="+e);//e=0

}

注:">>"代表算术右移,"<<"代表算术左移,">>>"代表逻辑右移

 

2、请回答在java中,下面的表达式运算的结果是:

~2=?//-3

2&3=?   //2

2|3=?   //3

~-5=?   //4

13&7=?  //5

5|4=?   //5

-3^3=?  //-2

注:"~"代表位取反,"&"代表位与,"|"代表位或,"^"代表位异或

 

二进制--基本概念

二进制是逢2进位的进位制,0、1是基本算符。

    现代的电子计算机技术全部采用的是二进制,因为它只使用0、1两个数字符号,非常简单方便,易于用电子方式实现。计算机内部处理的信息,都是采用二进制数来表示的。二进制(Binary)数用0和1两个数字及其组合来表示任何数。进位规则是“逢2进1”,数字1在不同的位上代表不同的值,按从右至左的次序,这个值以二倍递增。

注:1个字节=8位bit,

bit最高位是符号位如:■□□□□□□□黑色方框为符号位。

符号位0代表正数,1代表负数

 

二进制--原码、反码、补码

对于有符号的而言:

1、二进制的最高位是符号位:0表示正数,1表示负数

2、正数的原码、反码、补码都一样

3、负数的反码=它的原码符号位不变,其它位取反

4、负数的补码=它的反码+1

5、0的反码,补码都是0

6、java没有无符号数,换言之,java中的数都是有符号的

7、在计算机运算的时候,都是以补码的方式来运算的。

 

位运算符和移位运算

java中有4个位运算,分别是“按位与&、按位或|、按位异或^,按位取反~”,它们的运算规则是:

按位与&:两位全为1,结果为1

按位或|:两位有一个为1,结果为1

按位异或^:两位一个为0,一个为1,结果为1

按位取反:0->1,1->0

 

java中有3个移位运算符:

>>、<<算术右移和算术左移,运算规则:

算术右移:低位溢出,符号位不变,并用符号位补溢出的高位

算术左移:符号位不变,低位补0

>>>逻辑右移,运算规则是:低们溢出,高位补0

 

 

计算过程举例

注意:计算机运算的时候,都是以补码的方式来运算的,如果补码计算结果负数,则需要把补码转为原码

1>>2

1的原码

00000000 00000000 00000000 00000001

因为正数的原码、反码、补码都一样

所以1的补码

00000000 00000000 00000000 00000001

算数右移2位结果

00000000 00000000 00000000 00000000

所以1>>2=0 

推导出1>>n(n>1的正整数) 结果都为0

 

-1>>2

-1的原码

10000000 00000000 00000000 00000001

-1的反码

11111111 11111111 11111111 11111110

-1的补码

11111111 11111111 11111111 11111111

算数右移2位结果

11111111 11111111 11111111 11111111

补码->反码 :-1

11111111 11111111 11111111 11111110

反码->原码

10000000 00000000 00000000 00000001

所以-1>>2=-1

推导出-1>>n(n>1的正整数) 结果都为-1

 

3>>>2

3的原码

00000000 00000000 00000000 00000011

因为正数的原码、反码、补码都一样

所以3的补码

00000000 00000000 00000000 00000011

 

>>>逻辑右移2位结果为

00000000 00000000 00000000 00000000

所以3>>>2=0

 

~2

2的原码补码相同

2的补码

00000000 00000000 00000000 00000010

 

按位取反~

11111111 11111111 11111111 11111101

因为第1为是1,为负数,所以要-1,其它位取反得原码结果

-1

11111111 11111111 11111111 11111100

其它位取反

10000000 00000000 00000000 00000011

所以结果为-3

© 著作权归作者所有

HelloRookie
粉丝 4
博文 149
码字总数 26183
作品 0
广州
程序员
私信 提问
Java 中int与byte数组转换详解

1、与运算符的理解(&): 参加运算的两个数据,按二进位进行“与”运算。如果两个相应的二进位都为1,则该位的结果值为1,否则为0。即 0&0=0;0&1=0;1&0=0;1&1=1; 例子:int x = 6225555...

jiachcheng
2012/12/21
33.6K
0
JAVA移位运算 << 郏高阳

移位运算符就是在二进制的基础上对数字进行平移。按照平移的方向和填充数字的规则分为三种:<<(左移)、>>(带符号右移)和>>>(无符号右移)。 在移位运算时,byte、short和char类型移位后...

郏高阳
2011/08/30
521
0
Java二进制位运算、移位运算>>、>>

Java二进制位运算、移位运算 思考题 1、请看下面的代码段,回答a,b,c,d,e结果是多少? 注:">>"代表算术右移,"<<"代表算术左移,">>>"代表逻辑右移 2、请回答在java中,下面的表达式运算的结......

郑加威
2017/03/09
65
0
Int与byte[]互转详解分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_35959554/article/details/85334775 我先贴出最终转换的代码,再来进行一步一步的介绍:...

浪克oo
2018/12/29
0
0
LeetCode:Number of 1 Bits - 整数的汉明重量

1、题目名称 Number of 1 Bits(整数的汉明重量) 2、题目地址 https://leetcode.com/problems/number-of-1-bits/ 3、题目内容 英文:Write a function that takes an unsigned integer and......

北风其凉
2015/08/12
329
0

没有更多内容

加载失败,请刷新页面

加载更多

作为一个(IT)程序员!聊天没有话题?试试这十二种技巧

首先呢?我是一名程序员,经常性和同事没话题。 因为每天都会有自己的任务要做,程序员对于其他行业来说;是相对来说比较忙的。你会经常看到程序员在发呆、调试密密麻麻代码、红色报错发呆;...

小英子wep
今天
15
0
【SpringBoot】产生背景及简介

一、SpringBoot介绍 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程,该框架使用了特定的方式来进行配置,从而使开发人员不再需要...

zw965
今天
5
0
简述并发编程分为三个核心问题:分工、同步、互斥。

总的来说,并发编程可以总结为三个核心问题:分工、同步、互斥。 所谓分工指的是如何高效地拆解任务并分配给线程,而同步指的是线程之间如何协作,互斥则是保证同一时刻只允许一个线程访问共...

dust8080
今天
6
0
OSChina 周四乱弹 —— 当你简历注水但还是找到了工作

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌 :#今日歌曲推荐# 分享成龙的单曲《男儿当自强》。 《男儿当自强》- 成龙 手机党少年们想听歌,请使劲儿戳(这里) @hxg2016 :刚在...

小小编辑
今天
3.4K
22
靠写代码赚钱的一些门路

作者 @mezod 译者 @josephchang10 如今,通过自己的代码去赚钱变得越来越简单,不过对很多人来说依然还是很难,因为他们不知道有哪些门路。 今天给大家分享一个精彩的 GitHub 库,这个库整理...

高级农民工
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部