【问题标题】:How does bitshifting work in Java?移位在 Java 中是如何工作的?
【发布时间】:2011-03-19 18:39:18
【问题描述】:

我有这样的声明:

假设字节x的位值为00101011。x>>2的结果是什么?

我该如何编程,有人可以解释一下我在做什么吗?

【问题讨论】:

    标签: java bitwise-operators


    【解决方案1】:

    首先,你可以在java中移动byte,你只能移动intlong。所以byte会先升级,例如

    00101011 -> 00000000000000000000000000101011

    11010100 -> 11111111111111111111111111010100

    现在,x >> N 表示(如果您将其视为二进制数字字符串):

    • 最右边的 N 位被丢弃
    • 最左边的位会根据需要复制多次,以将结果填充到原始大小(32 或 64 位),例如

    00000000000000000000000000101011 >> 2 -> 00000000000000000000000000001010

    11111111111111111111111111010100 >> 2 -> 11111111111111111111111111110101

    【讨论】:

    • 11010100 是否会被视为负数,因为它的最左边是 1? \
    • @Pha3drus,是的,假设数字存储在 2 的补码中。见stackoverflow.com/questions/1049722/what-is-2s-complement
    • 我尝试在 java 中转换 int 使用:@Test public void testBinaryString() { int n = 4;诠释 v = n >> 1; System.out.println("v = " + v + ", n = " + n);但我得到输出:v = 2, n = 4。想知道为什么它不会将 n 更改为 2?
    • 帮助。我正在尝试获取 int 的第 32 位并获得不良行为。当我屏蔽该位并将其移至第一个位置时,我得到 -1 而不是 1。
    【解决方案2】:

    00101011 的二进制 32 位是

    00000000 00000000 00000000 00101011,结果是:

      00000000 00000000 00000000 00101011   >> 2(times)
     \\                                 \\
      00000000 00000000 00000000 00001010
    

    将 43 的位向右移动距离 2;用左侧的最高(符号)位填充。

    结果为 00001010,十进制值为 10。

    00001010
        8+2 = 10
    

    【讨论】:

      【解决方案3】:

      当您右移 2 位时,您会删除 2 个最低有效位。所以:

      x = 00101011
      
      x >> 2
      
      // now (notice the 2 new 0's on the left of the byte)
      x = 00001010
      

      这本质上与将一个 int 除以 2、2 倍相同。

      在 Java 中

      byte b = (byte) 16;
      b = b >> 2;
      // prints 4
      System.out.println(b);
      

      【讨论】:

      • 每次右移除以 2,所以两次右移除以 4。
      • 没错。或者,在数学语言中:n >> m -> n / (2^m)
      • @delnan,是的,但这看起来很吓人。
      • 如果在位移后向左显示填充 0 可能会更清晰一些。
      • 您不能在 Java 编程语言中对 byte 数据类型进行按位移位操作。
      【解决方案4】:

      这些示例涵盖了应用于正数和负数的三种类型的移位:

      // Signed left shift on 626348975
      00100101010101010101001110101111 is   626348975
      01001010101010101010011101011110 is  1252697950 after << 1
      10010101010101010100111010111100 is -1789571396 after << 2
      00101010101010101001110101111000 is   715824504 after << 3
      
      // Signed left shift on -552270512
      11011111000101010000010101010000 is  -552270512
      10111110001010100000101010100000 is -1104541024 after << 1
      01111100010101000001010101000000 is  2085885248 after << 2
      11111000101010000010101010000000 is  -123196800 after << 3
      
      
      // Signed right shift on 626348975
      00100101010101010101001110101111 is   626348975
      00010010101010101010100111010111 is   313174487 after >> 1
      00001001010101010101010011101011 is   156587243 after >> 2
      00000100101010101010101001110101 is    78293621 after >> 3
      
      // Signed right shift on -552270512
      11011111000101010000010101010000 is  -552270512
      11101111100010101000001010101000 is  -276135256 after >> 1
      11110111110001010100000101010100 is  -138067628 after >> 2
      11111011111000101010000010101010 is   -69033814 after >> 3
      
      
      // Unsigned right shift on 626348975
      00100101010101010101001110101111 is   626348975
      00010010101010101010100111010111 is   313174487 after >>> 1
      00001001010101010101010011101011 is   156587243 after >>> 2
      00000100101010101010101001110101 is    78293621 after >>> 3
      
      // Unsigned right shift on -552270512
      11011111000101010000010101010000 is  -552270512
      01101111100010101000001010101000 is  1871348392 after >>> 1
      00110111110001010100000101010100 is   935674196 after >>> 2
      00011011111000101010000010101010 is   467837098 after >>> 3
      

      【讨论】:

        【解决方案5】:

        &gt;&gt; 是算术右移运算符。第一个操作数中的所有位都移动了第二个操作数指示的位数。结果中最左边的位被设置为与原始数字中最左边的位相同的值。 (这是为了让负数保持负数。)

        这是您的具体情况:

        00101011
          001010 <-- Shifted twice to the right (rightmost bits dropped)
        00001010 <-- Leftmost bits filled with 0s (to match leftmost bit in original number)
        

        【讨论】:

          【解决方案6】:
          public class Shift {
           public static void main(String[] args) {
            Byte b = Byte.parseByte("00101011",2);
            System.out.println(b);
            byte val = b.byteValue();
            Byte shifted = new Byte((byte) (val >> 2));
            System.out.println(shifted);
          
            // often overloked  are the methods of Integer
          
            int i = Integer.parseInt("00101011",2);
            System.out.println( Integer.toBinaryString(i));
            i >>= 2;
            System.out.println( Integer.toBinaryString(i));
           }
          }
          

          输出:

          43
          10
          101011
          1010
          

          【讨论】:

            【解决方案7】:
            byte x = 51; //00101011
            byte y = (byte) (x >> 2); //00001010 aka Base(10) 10
            

            【讨论】:

              【解决方案8】:

              您不能在 Java 中编写像 00101011 这样的二进制文字,因此您可以改为使用十六进制:

              byte x = 0x2b;
              

              要计算x &gt;&gt; 2 的结果,您可以准确地写出来并打印结果。

              System.out.println(x >> 2);
              

              【讨论】:

              • 关于 Byte.parseByte("00101011",2); ?
              • 这是在编译时计算的还是在运行时导致方法调用?
              • Java 7 应该添加二进制文字,例如:0b00101011
              • @Alan Kreuger:这是个好消息。 :) 感谢您的信息。
              【解决方案9】:

              您可以使用例如如果您想查看您的数字的 bitString 表示,请使用此 API。 Uncommons Math

              示例(在 jruby 中)

              bitString = org.uncommons.maths.binary.BitString.new(java.math.BigInteger.new("12").toString(2))
              bitString.setBit(1, true)
              bitString.toNumber => 14
              

              编辑:更改 api 链接并添加一个小示例

              【讨论】:

              • 上述网址已失效。请删除/编辑它以指向正确的网页。
              • 更新了链接。我不确定这个答案是否会改变问题..
              • 您保存的 HTTP 请求带有无效 URL!
              【解决方案10】:

              00101011 = 十进制的 43

              class test {    
                  public static void main(String[] args){
                     int a= 43;       
                     String b= Integer.toBinaryString(a >> 2);        
                     System.out.println(b);
                  }   
              }
              

              输出:

              101011 变成 1010

              【讨论】:

              • 您能否说明此答案与此处发布的其他答案的区别?
              猜你喜欢
              • 2015-05-08
              • 1970-01-01
              • 2012-06-10
              • 1970-01-01
              • 2012-03-22
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多