关于移位运算符号的几个模糊的地方

max_min 2005-07-09 09:24:43
大家都知道java有关整数的移位运算符有三个<< ,>>, >>>。但是我看了几本书对他们都是一带而过有一个问题一直困扰着我。
书上都说〈〈右移动n位这个运算是起到2的n次方的作用,但是显然如果移出去的位里有1的话结果就不会增大2的n次方的作用了,其结果就是不可预测的,但是我看了java核心技术和java编程思想都没有涉及这个问题,都是一带说是增大2的n次方的作用。显然这个两个〉〉 , >>>也有移出的位有1的话错误的问题。
希望指点,谢谢!
...全文
425 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
njwangchuan 2005-07-10
  • 打赏
  • 举报
回复

昨天说的有个重大错误,负数右移的时候如果出现全1说明超出了机器的表示范围,特此更正!
interhanchi 2005-07-10
  • 打赏
  • 举报
回复
java里面的移位,就是用补码来移位的!也就是补码移位.
fishland 2005-07-10
  • 打赏
  • 举报
回复
"书上都说〈〈右移动n位这个运算是起到2的n次方的作用,但是显然如果移出去的位里有1的话结果就不会增大2的n次方的作用了,其结果就是不可预测的,.."
首先纠正楼主错误,‘<<’为左移符号。是这样的,左移在补码中只是在末尾加0,起到扩大2的n次方的作用。
比如101这个二进制数,也就是5(十进制),左移一位后变为1010,十进制是10,起到了x2的作用。这里所说的“如果移出去的位里有1的话结果就不会增大2的n次方的作用了,其结果就是不可预测的”是指:如果对数的长度有要求,比如只能用3位二进制表示整数,还用上面的例子101,移动一位后是010,第一个1已经移出去,结果是2(十进制),没有扩大2倍,所以他说其结果就是不可预测的。

而楼主下面的话:
"显然这个两个〉〉 , >>>也有移出的位有1的话错误的问题。" 是错误的。因为右移和左移的规律是不同的,移位后的第一位是“按符号移动”,就不会出现以上问题。

所以,楼主的书上所言是完全正确的。

还要说明一点,一定要清楚数字在机器内部是按补码存储的,比如 int a=5,在内部,已经存储为00000000000000000000000000000101(32位),而不用你做任何转换。


  • 打赏
  • 举报
回复
关于移位操作
<< 往左移 是1补1,是0补0。 左移n位就是乘以2的n次方。
>> 往右移 是1补1,是0补0。 右移n位就是除以2的n次方。
>>> 无符号右移 始终补0。
max_min 2005-07-10
  • 打赏
  • 举报
回复
感谢个位的回复,昨天在机器上狂试验了一下,感觉应该是这么回事情。
首先说<<左移。别说左移出二进制1会出问题,就是左移出0的话超出变量的表示范围也一样会出问题
也就是说,左移的前提是不要超出数的表示范围的话,2的n次方这个结论还是正确的。例子是int x=0x8fffffff;x<<1(超出数的表示范围)。之所以会犯我以前认识上的错误,是因为写成十进制后忽略了前面有那么多零比如说int i=5;事实上因为int有32位存储,要左移29次的话才会超出范围。但是>>就不一样了很容易就能把二进制1移出去这样得到的结果其实是整除2的n次方的结果
Goldrush 2005-07-10
  • 打赏
  • 举报
回复
借问c语言中->是做什么用的?
奇伢 2005-07-09
  • 打赏
  • 举报
回复
路过,这些我以前也都学习过
njwangchuan 2005-07-09
  • 打赏
  • 举报
回复
有很重要的一点楼主没有搞清楚,就是机器数的存放是用补码.

1、正数移动。正数由于首位是零,所以在没有溢出的情况,左移末位补0,右移首位补0。如果左移后首位,变1,这个数就变成负数了了,说明正溢出了。右移动如果全变0,说明这个数已经小于机器数可表示范围(int型小于1大于0了)

2、负数移动。规则基本类似,左移的时候末位补0,如果首位变0,说明此数负溢出,右移的时候首位保持1,如果除了首位其他都是0,说明此数已经超出表示范围(int型小于0大与-1)

应该够详细了吧
kingfish 2005-07-09
  • 打赏
  • 举报
回复
System.out.println(Integer.toHexString(0xFFFFFFFF >>> 8));//>>>无符合右移,填0,所以结果是0x00FFFFFF
System.out.println(Integer.toHexString(0xFFFFFFFF >> 8));//>>有符合右移(符号高位决定),,所以结果是0xFFFFFFFF ,即 -1
System.out.println(Integer.toHexString(0x000000FF<< 8));//左移,,所以结果是0xFFFFFF00
max_min 2005-07-09
  • 打赏
  • 举报
回复
夜雨兄弟如果真懂的话你就说说详细,我在网上查了很多资料没找到,在这里先谢了
max_min 2005-07-09
  • 打赏
  • 举报
回复
congliu()你好
你说的话我明白事实上如果作为int形的变量,左移n位的话,java自动对n取模32(因为int一共有32位,如果是long形就取模64)如果调试int i;i<<34和i<<2结果i都会是4。但是显然作为int的01011110000000000000000000000000左移两位结果就不对了,而且它也没出他的表示范围,楼上有的兄弟回答的太草率
max_min 2005-07-09
  • 打赏
  • 举报
回复
不是带不带符号的问题,比如说二进制正数01011110左移两位的结果是多少,肯定不是简单的增大或缩小2的2方的问题
congliu 2005-07-09
  • 打赏
  • 举报
回复
楼主说得没错,但是<<使用时有个前提,就是运算的结果必须在进行运算的对象的取值范围内,所以楼主所说的 “显然如果移出去的位里有1的话结果就不会增大2的n次方的作用了,其结果就是不可预测的” 是不准确的。

yeyu710 2005-07-09
  • 打赏
  • 举报
回复
带符号的运算,它还有一个标识位的啊
yeyu710 2005-07-09
  • 打赏
  • 举报
回复
呵呵,这个问题可到到一般的计算机基础知识的书上就可以找到了啊!

62,617

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧