Java的移位运算

Java的移位运算前言计算机支持两种移位运算 分别是向左移位 x lt k 和向右移位 x gt k 左移位会对输入的操作数舍弃最高的 k 位 并在右端补 k 个 0 而右移位运算却分为两种情况 分别是逻辑右移和算术右移 也叫无符号右移和符号右移 在逻辑右移中 会对操作数舍弃最低的 k 位 并在左端补 k 个 0 在算术运算中 则对操作数舍弃最低的 k 位 并在左端补 k 个最高有效位的值 对于有符号数来说 最高位有效值是不同的 所以逻辑右移和算术右移将产生不同的效果 而 C 语言并没有明确定义有符号数该使用哪种类型的右移 k 和向右移位 x

前言

计算机支持两种移位运算,假设操作数为x,移动的位数为k,则向左移位是 x << k,向右移位是 x >> k。左移位会对输入的操作数舍弃最高的k位,并在右端补k个0。而右移位运算却分为两种情况,分别是逻辑右移和算术右移(也叫无符号右移和符号右移),在逻辑右移中,会对操作数舍弃最低的k位,并在左端补k个0,在算术运算中,则对操作数舍弃最低的k位,并在左端补k个最高有效位的值。

对于有符号数来说,最高位有效值是不同的,所以逻辑右移和算术右移将产生不同的效果,而C语言并没有明确定义有符号数该使用哪种类型的右移,虽然两种右移都可以,但是现在几乎所有的编译器/机器组合都会对有符号数使用算术右移。而Java比C强大的一个地方在于它对右移有明确的定义,规定 x >> k 使用算术右移, x >>> k 使用逻辑右移。

本文将通过几个实际的例子,并手动计算二进制执行过程,来探究当操作数分别为正数和负数时,Java的移位运算是怎么实现的。

左移位运算

左移运算也相当于做乘法运算,乘积因子为 2^k。例如,我们执行149 << 4,相当于执行了 149*16 = 2384。

1)正数左移位运算

System.out.println (149 << 4); System.out.println (Integer.toBinaryString ( 149 << 4 ));
2384 0

149 << 4 的计算过程如下:

输入:            149

转为二进制:

展开32位:       00000000 00000000 00000000

丢弃最高4位:  0000 00000000 00000000

右端补4个0: 0000 00000000 00000000 0000

忽略符号位: 0000

转为十进制: 2384

可以看出,我们计算过程的最后两步和程序打印效果完全一致。

2)负数左移位运算

System.out.println (-149 << 4); System.out.println (Integer.toBinaryString ( -149 << 4 ));
-2384 

-149 << 4 的计算过程如下:

输入:            -149

转为二进制: 0         (ps: 绝对值二进制取反再加1。)

丢弃最高4位:  1111 0

右端补4个0: 1111 0 0000

以上是个负数二进制,现要转成十进制,按照以下三步进行:

                       1111  00 1111      (减1)

                       0000 00000000 00000000 0000(取反)

                      - 0000                                           (忽略符号位,并添负号)

转为十进制: -2384

可以看出,我们计算过程的第4步和最后一步的计算结果和程序打印效果完全一致。

右移位运算

右移运算也相当于做除法运算,被除数为 2^k。例如,我们执行149 >> 4,相当于执行了 149/16 = 9。

1)正数右移运算

Java的基本类型数据都是有符号数,最高位为1表示负数,最高位为0表示正数。所以对于正数来说,逻辑右移和算术右移没有任何区别,因为都是在左端补0。

System.out.println (149 >> 4); System.out.println (Integer.toBinaryString ( 149 >> 4 )); System.out.println (149 >>> 4); System.out.println (Integer.toBinaryString ( 149 >>> 4 ));
9 1001 9 1001

149 >> 4 计算过程:

输入:            149

转为二进制:

展开32位:     00000000 00000000 00000000

丢弃最低4位:00000000 00000000 00000000 1001

左端补4个0:  0000 00000000 00000000 00000000 1001

忽略符号位:  1001

转为十进制:  9

149 >>> 4 的计算过程和上面完全一样,左端都是补4个0,所以打印效果当然是一致的。

2)负数右移运算

当输入的数据是负数,此时逻辑右移和算术右移将产生较大区别。由于负数高位是1,所以逻辑右移和算术右移在左端分别补0和1。

System.out.println (-149 >> 4 ); //负数的算术右移 System.out.println (Integer.toBinaryString ( -149 >> 4 )); System.out.println (-149 >>> 4 ); //负数的逻辑右移 System.out.println (Integer.toBinaryString ( -149 >>> 4 ));
-10   

a)-149 >> 4 计算过程(负数的算术右移):

输入:           -149

转为二进制:    0         (ps: 绝对值二进制取反再加1。)

丢弃最低4位: 0110

左端补4个1:1111 0110

相应十进制:  -0000 00000000 00000000 00000000 0101   (ps: 减1,取反,添负号。)

转为十进制:-10

可以看出,我们第4步和第6步运算结果和代码打印的前两行完全一致。

b)-149 >>> 4 计算过程(负数的逻辑右移):

输入:               -149

转为二进制:    0       (ps: 绝对值二进制取反再加1。)

丢弃最低4位:  0110

左端补4个0: 0000 0110

转为十进制:

可以看出,我们第3步和第5步运算结果和代码打印的后两行完全一致。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/222632.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午3:20
下一篇 2026年3月17日 下午3:20


相关推荐

  • navicat激活2022【中文破解版】[通俗易懂]

    (navicat激活2022)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~1TCF2R91JZ-eyJsaWNlb…

    2022年3月31日
    309
  • Mysql 日期类型比较 TIMESTAMPDIFF

    Mysql 日期类型比较 TIMESTAMPDIFF  在数据库查询中,经常遇到计算2个日期相差值,SQL提供一个非常有用的函数:TIMESTAMPDIFFT。  基本语法:TIMESTAMPDIFF(interval,datetime_expr1,datetime_expr2)    其中,interval的取值可以为:SECOND,MINUTE,HOUR,DAY,WEEK,MONTH,QUARTERorYEAR   …

    2022年5月18日
    92
  • numpy转torch.tensor_tensorflow numpy

    numpy转torch.tensor_tensorflow numpy要对tensor进行操作,需要先启动一个Session,否则,我们无法对一个tensor比如一个tensor常量重新赋值或是做一些判断操作,所以如果将它转化为numpy数组就好处理了。下面一个小程序讲述了将tensor转化为numpy数组,以及又重新还原为tensor:importtensorflowastfimg1=tf.constant(value=[[[[1],[2],[3],[4…

    2022年10月9日
    4
  • git log 查看 当前分支的 提交历史[通俗易懂]

    git log 查看 当前分支的 提交历史[通俗易懂]gitlog查看当前分支的提交历史在提交了若干更新之后,想回顾下提交历史,可以使用gitlog命令查看默认不用任何参数的话,gitlog会按提交时间列出所有的更新,最近的更新排在最上面。看到了吗,每次更新都有一个SHA-1校验和、作者的名字和电子邮件地址、提交时间,最后缩进一个段落显示提交说明。gitlog有许多选项可以帮助你搜寻感兴趣的提交,接下来我们…

    2022年8月22日
    15
  • linux-kernel(内核)升级,降级与使用

    linux-kernel(内核)升级,降级与使用linux-kernel(内核)升级,降级与使用

    2022年4月24日
    54
  • OpenClaw 部署文档

    OpenClaw 部署文档

    2026年3月13日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号