Java位移运算

最近在补习Java基础,位移运算是今天的主角。

在此之前我们要先来复习下计算机二进制的一些概念。

在计算机硬件的世界里,芯片,处理器等所处理的电信号都为高低电平,即为10信号。

顺接上篇的一个概念来讲下:字节(byte)

1 byte = 8bit(位) 也就是一个字节相当于8位(0000 0000)

如果是两个字节那就是16位 0000 0000 0000 0000

计算机里的数也分有符号数跟无符号数, 有符号数的最高位表示符号正0/负1, 而无符号数的最高位跟其他位一样表示实际的数。

今天只说有符号数:

正数:即最高位为0,比如 0000 0001 为 1

负数:最高位为1, 比如 1000 0011 为 -3

这二进制是怎么算成我们生活中常用的十进制数呢?

1000 0011 = 去掉最高位的1(符号-),剩下的从右往左依次是以2为底数,从0开始间隔为1的幂数

上面的计算是 -(2^0+2^1) = -3

所以 8位有符号数的范围是[-127, 127]

1111 1111 = -(2^0+2^1+2^2+2^3+2^4+2^5+2^6) = -127

0111 1111 = 2^0+2^1+2^2+2^3+2^4+2^5+2^6 = 127

上面的正数负数皆为我们我们容易理解的写法。在计算机里,正数以其原码,负数以其补码计算。

原码,反码,补码:

正数的原码、反码、补码皆为其本身;

负数的原码是其本身,

负数的反码: 最高位(符号位不变),其余全部取反, 0变1, 1变0, 1000 0011(原码) => 1111 1100(反码)

负数的补码: 反码的基础上加1,这里有个注意点是,二进制是逢2进1. 

1000 0011(原码) => 1111 1100(反码) => 1111 1101(补码)

讲完了上面的基础,正是进入正题,位移运算,顾名思义:位置的移动运算;

左移:正数负数都在右侧补0,负数最高位不变

右移:正数补0, 负数最高位不变,空位补1

下面有段Java的位移运算代码:

public static void main(String[] args) {
		System.out.println(6 >> 2);
		System.out.println(-8 << 3);
		System.out.println(-9 >> 1);
	}

运算结果如下:

1
-64
-5

先来算第一个: 6 >> 2

6的二进制为: 0000 0110 = 2^1+2^2 = 6

往右移2位,0000 0001 = 2^0 = 1

接着来算第二个:-8 << 3

-8的二进制:                  1000 1000 = -(2^ 3) = -8

负数以补码形式计算:   1111  0111(反码) => 1111 1000(补码)

最高位(符号位)不动,其余向左移动3位,空位补0, 1001 0000 移动后的依旧为补码,我们需要还原为原码:

1100 0000 减1 => 1011 1111 取反 => 1100 0000 =  -(2^6) = -64

然后算第三个:-9 >> 1

-9的二进制:        1000 1001 = -(2^0+2^3) = -9

负数以补码运算: 1111 0110(反码)加1=> 1111 0111

最高位不动, 其余位向右移动1位, 空位补1, 1111 1011(补码)

1111 1011 减1 => 1111 1010 取反 => 1000 0101 = -(2^0+2^2) = -5

至此,例子解析完毕,有问题请指教。

 

 

 

 

 

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值