A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© HM汪磊 高级黑马   /  2013-2-28 12:55  /  3523 人查看  /  25 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

class  Yiwei
{
        public static void main(String[] args)
                {
                        int x=6;
                        x=x>>>32;
                        System.out.println("x="+x);       
                }

}


此程序输出结果为X=6.求解???运算符>>>有什么特殊要求吗???

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1 新人,鼓励一下,这部分老师的视频里说得挺.

查看全部评分

25 个回复

倒序浏览
class  Yiwei
{
        public static void main(String[] args)
                {
                        int x=6;     //x  赋值
                        x=x>>>32;  //X=6 右移32位  也就是 000000000000000000000000000000006
                        System.out.println("x="+x);        
                }

}


>>>是不带符号位的右移,x>>>32就是x的内容右移一位,开头补0(x的内容并不改变)   个人理解 希望正确
回复 使用道具 举报
这个吧,首先要明白这个原码和算术移位以及逻辑移位。
x>>>32,是指x右移32位。这个是指不带符号的算术移位,也就是不管左移还是右移,都补零。而逻辑移位呢,是带符号的移位,此处不详细解释。
x=6,计算机里存储是补码形式存储,而正数的补码和原码是一样的,所以算术移位后还是6.
希望你能理解。。。。。。

点评

前两行说的还挺对的,怎么后面又有问题了呢,你的答案老有问题,我可要不给分了。 十分以下,认真回答问题,鼓励一下。  发表于 2013-3-1 20:02

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
╯两路人_、陌路 发表于 2013-2-28 13:42
class  Yiwei
{
        public static void main(String[] args)

计算机存储是按二进制补码形式存储的 6 在计算机中的存储是 00000000 00000000 00000000 00000110  由于是>>> 无符号的右移  所以低位舍去 高位补0

对于byte、short、char和int进行移位时,规定实际移 动的次数是移动次数和32的余数,也就是移位33次和移位1次得到的结果相同。移动long型的数值时,规定实际移动的次数是移动次数和64的余数,也就 是移动66次和移动2次得到的结果相同。  

楼主的x为int类型   
硬件把移位对字长进行取模,右移32位就是右移了0位(CPU 把右移的位数 32 对于字长 32 进行取模运算,得到 0),因此6 右移 32 位仍然是 6。



回复 使用道具 举报
赵海洋 发表于 2013-2-28 14:27
这个吧,首先要明白这个原码和算术移位以及逻辑移位。
x>>>32,是指x右移32位。这个是指不带符号的算术移位 ...

二楼 有点不是正确吧  这么说来x=6 >>>1  后也等于6喽?   可以验证下  等3 的
回复 使用道具 举报
刘凯 发表于 2013-2-28 14:35
二楼 有点不是正确吧  这么说来x=6 >>>1  后也等于6喽?   可以验证下  等3 的 ...

右移一位少个0,最后两位11,是3啊。我不是在说右移32位怎么移的么。。。看来还是没说明白,表达能力有点差。。。:dizzy:
回复 使用道具 举报
好吧,我应该这么说,对于这个6,就这么理解,换成32位的二进制,往右移位,左边补零,右边去掉,然后如果字长是32位的,小于32位就移,大于32就取模。怎么感觉我还是没说明白似的。。。。
回复 使用道具 举报
刘凯 金牌黑马 2013-2-28 14:51:20
8#
赵海洋 发表于 2013-2-28 14:47
右移一位少个0,最后两位11,是3啊。我不是在说右移32位怎么移的么。。。看来还是没说明白,表达能力有点 ...

骚年 好好学习  天天向上 啊要{:3_52:}
回复 使用道具 举报
刘凯 发表于 2013-2-28 14:51
骚年 好好学习  天天向上 啊要

要要  切克闹~~~咱俩这不算刷回复吧。。。。
回复 使用道具 举报
赵海洋 发表于 2013-2-28 14:52
要要  切克闹~~~咱俩这不算刷回复吧。。。。

不说了,要不给禁闭了     斑竹万岁 万岁 万万岁  求分 求高升 ~

点评

我表示啥也没看到。。。 - -  发表于 2013-3-2 09:55
回复 使用道具 举报
刘凯 发表于 2013-2-28 14:32
计算机存储是按二进制补码形式存储的 6 在计算机中的存储是 00000000 00000000 00000000 00000110  由于 ...

恩,正解。但我对byte类型尝试的时候有点疑惑了,http://msdn.microsoft.com/zh-cn/library/x0ax6803(VS.80).aspx中的举例
  1. class  WyDemo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.             byte x=15;//x被赋值为 00001111
  6.                 x>>>=10;//无符号右移10位。实际位移2位,应得00000011=3
  7.                 System.out.println(x);
  8.         }
  9. }
复制代码
可是运行的结果是0啊 求解啊 难道我2了

位移.PNG (5.92 KB, 下载次数: 38)

位移.PNG
回复 使用道具 举报
本帖最后由 孙传磊 于 2013-2-28 15:40 编辑

>>> 操作符,无符号算数右移,左面补0
由于无符号右移运算符>>>只是对32位和64位的值有意义。因为要记住,在表达式中过小的值总是被自动扩大为int型。这意味着符号位扩展和移动总是发生在32位而不是8位或16位。
如果变量定义为 int 型 ,那么要是 移位的次数 大于 32   就会把移位次数与32做取模,之后再做移位。
同理变量定义为 long 型 ,那么要是 移位的次数 大于 64   就会把移位次数与64做取模,之后再做移位。
下面举例说明:
例如:
  public class Yiwei {
          public static void main(String[] args)
      {
              long x=6;         //此处把int改为long   结果输出的就是 0 了
              x=x>>>32;
              System.out.println("x="+x);        
      }
}
上面的函数输出结果是 0  
若把  x=x>>>32;  中的32改成 64 那么结果又是 6 了
  现在 把上面的成员变量 x 定义为 int型
  再把  x=x>>>32;  中的32改成 33 那么结果  和  x=x>>>1;的结果是一样的
  再把  x=x>>>32;  中的32改成 34 那么结果  和  x=x>>>2;的结果是一样的
  也就是把  x=x>>>32;   和  x=x>>>0;的结果是一样的 也就是问题中的结果 6

点评

小于32或64也可以取模哦  发表于 2013-2-28 17:49
回复 使用道具 举报
袁术森 发表于 2013-2-28 15:26
恩,正解。但我对byte类型尝试的时候有点疑惑了,http://msdn.microsoft.com/zh-cn/library/x0ax6803(VS. ...

如楼上所说 :“由于无符号右移运算符>>>只是对32位和64位的值有意义。因为要记住,在表达式中过小的值总是被自动扩大为int型。这意味着符号位扩展和移动总是发生在32位而不是8位或16位。”

你说的这个 我也不知道是个什么情况  ,, 高手解答吧
回复 使用道具 举报
顶12楼  int类型的>>>32等于>>>0    值不变.
回复 使用道具 举报
如果变量定义为 int 型 , 把移位次数与32做取模,之后再做移位。
若变量定义为 long 型 ,把移位次数与64做取模,之后再做移位。
回复 使用道具 举报
孙传磊 发表于 2013-2-28 15:33
>>> 操作符,无符号算数右移,左面补0
由于无符号右移运算符>>>只是对32位和64位的值有意义。因为要记住, ...

是的 ,我个人认为  如果 直接取模运算是不是每一次位移都要进行一次取模运算?
现在我想知道的是 如果做一次判断 (判断是否小于 32或64) 会不会在性能上
比每一次位移都要进行一次取模运算更优越一些?
回复 使用道具 举报
袁术森 发表于 2013-2-28 15:26
恩,正解。但我对byte类型尝试的时候有点疑惑了,http://msdn.microsoft.com/zh-cn/library/x0ax6803(VS. ...

例子里的字长是8位,15是0000 1111,右移10位相当于右移两位。你计算机字长32位,15是0000 0000 0000 0000 0000 0000 0000 1111,右移十位之后是0000 0000 0000 0000 0000 0000 0000 0000,所以是0.
回复 使用道具 举报
孙传磊 发表于 2013-2-28 15:33
>>> 操作符,无符号算数右移,左面补0
由于无符号右移运算符>>>只是对32位和64位的值有意义。因为要记住, ...

只对32位或64位有意义?如果我机器字长,存储字长都是8位的,对8位的也可以做取模吧。这个应该跟字长有关。求解释~~
回复 使用道具 举报
本帖最后由 孙传磊 于 2013-2-28 19:37 编辑
刘凯 发表于 2013-2-28 16:26
如楼上所说 :“由于无符号右移运算符>>>只是对32位和64位的值有意义。因为要记住,在表达式中过小的值总 ...

java里就是这样规定的,下面的例子说明了这一点:
public class ByteShift {
        public static void main(String[] args) {
                char hex[]={'0','1','2','3','4','5','6','7',
                                '8','9','A','B','C','D','E','F'};
                byte b=(byte) 0xf1;
                byte c=(byte) (b>>4);
                byte d=(byte) (b>>>4);
                byte e=(byte) ((b & 0xff)>>4);
        System.out.println("    b=0x"+hex[(b>>4) & 0x0f]+hex[b & 0x0f]);
        System.out.println("    b>>4=0x"+hex[(c>>4) & 0x0f]+hex[c & 0x0f]);
        System.out.println("    b>>>4=0x"+hex[(d>>4) & 0x0f]+hex[d & 0x0f]);
        System.out.println("(b & 0xff)>>4=0x"+hex[(e>>4) & 0x0f]+hex[e & 0x0f]);
        }
}
输出结果:
    b=0xF1
    b>>4=0xFF
    b>>>4=0xFF
(b & 0xff)>>4=0x0F
该程序的输出显示了无符号右移运算符>>>对byte型值处理时,实际上不是对byte型值直接操作,而是将其扩大到int型后再处理
回复 使用道具 举报
刘凯 发表于 2013-2-28 16:26
如楼上所说 :“由于无符号右移运算符>>>只是对32位和64位的值有意义。因为要记住,在表达式中过小的值总 ...

java里就是这样规定的,下面的例子说明了这一点:
public class ByteShift {
        public static void main(String[] args) {
                char hex[]={'0','1','2','3','4','5','6','7',
                                '8','9','A','B','C','D','E','F'};
                byte b=(byte) 0xf1;
                byte c=(byte) (b>>4);
                byte d=(byte) (b>>>4);
                byte e=(byte) ((b & 0xff)>>4);
        System.out.println("    b=0x"+hex[(b>>4) & 0x0f]+hex[b & 0x0f]);
        System.out.println("    b>>4=0x"+hex[(c>>4) & 0x0f]+hex[c & 0x0f]);
        System.out.println("    b>>>4=0x"+hex[(d>>4) & 0x0f]+hex[d & 0x0f]);
        System.out.println("(b & 0xff)>>4=0x"+hex[(e>>4) & 0x0f]+hex[e & 0x0f]);
        }
}
输出结果:
    b=0xF1
    b>>4=0xFF
    b>>>4=0xFF
(b & 0xff)>>4=0x0F
该程序的输出显示了无符号右移运算符>>>对byte型值处理时,实际上不是对byte型值直接操作,而是将其扩大到int型后再处理
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马