Java 返回交换X的两个低阶字节的结果

Java 返回交换X的两个低阶字节的结果,java,bit-manipulation,bit-shift,Java,Bit Manipulation,Bit Shift,问题与解决方案: /** Return the result of swapping the two lower-order bytes of X. * For example, if X is 0x12345678, then swap(X) is 0x12347856. */ static int swapLower(int X) { /* Solution */ int lower = X & 0x0000ffff; int upper = X &

问题与解决方案:

/** Return the result of swapping the two lower-order bytes of X.
* For example, if X is 0x12345678, then swap(X) is 0x12347856. */
static int swapLower(int X) {
    /* Solution */
    int lower = X & 0x0000ffff;
    int upper = X & 0xffff0000;

    return upper | (0xffff & ((lower << 8) | (lower >> 8)));
}
  • int lower=X&0x0000ffff=X&0B0000000000000000111111111111=0b0000000000000000x15。。。x0

  • int upper=X&0xffff0000=X&0B11111111110000000000000000=0bx31。。。x16000000000000000

  • 下8=0b0000000000000000x15。。。x0>>8=0BSSSS00000000x15。。。x8

    • (假设
      X
      是一个有符号的数字,那么
      s
      是符号位;如果
      X
      为正,则为0;如果
      X
      为负,则为1)
  • (下>8)=0b00000000x15。。。x000000000 | 0BSSSS00000000x15。。。x8=0BSSSSX15。。。x0x15。。。x8

  • 0xffff&((下>8))=0B0000000000000000011111&0BSSSSX15。。。x0x15。。。x8=0b00000000000000000x7。。。x0x15。。。x8

  • 上部|(0xffff&((下部>8))=0bx31。。。X16000000000000000000000 | 0b00000000000000000x7。。。x0x15。。。x8=x31。。。x16x7。。。x0x15。。。x8


  • 给出的解决方案是正确的,但过于复杂,因此比必要的更难理解。以下解决方案更容易理解:

    return X & 0xffff0000 | ((X & 0xff00) >> 8) | ((X & 0xff) << 8);
    

    返回X&0xffff0000 |((X&0xff00)>>8)|((X&0xff)是的,这比必要的更难理解

    我认为这更容易理解:

    int lowest2     = (X & 0x000000FF) << 8; // lowest byte moved 8 bits left
    int nextLowest2 = (X & 0x0000FF00) >> 8; // next lowest byte move 8 bits right
    int upper4      = (X & 0xFFFF0000);
    return upper4 | lowest2 | nextLowest2;
    
    当然,如果你分析你给出的解决方案,你会得到同样的结果:

    如果上下定义为:

    int lower = X & 0x0000FFFF
    int upper = X & 0xffff0000;
    
    然后:

    X=0x12345678
    下限=0x00005678
    (下限>8)=0x00000056
    ((下>8))=0x00567856
    (0xFFFF&(下部>8))=0x00007856
    上限=0x12340000
    上|(0xffff&((下>8))=0x12345678
    
    你是说这是解决方案,而你不明白吗?我是说这是给定的解决方案,而且(1)我不明白(2)首先,我不知道如何推导它。请帮帮我!编辑看起来很正确,只是符号位的部分是一个小问题,因为步骤1已经清除了符号位,所以在步骤2-6中它始终为零。最后(步骤7)符号位被设置回x31,就像它在开始时一样。你能解释每个组件吗?我有麻烦了!你必须自己至少做一些思考。解决这个问题的一个好方法是运行各种不同的数字,用十六进制表示法,通过它,分别打印出表达式的每一部分,并尝试取消编号仔细观察他们的情况。试试0x12、0x2300、0x2345和0x12345678。@Marcelocontos我知道你是从哪里来的,但是如果他要求帮助解决方案,你提出另一个解决方案并告诉他去尝试,他理解的几率有多大?也许会给出一个更简单的解决方案并给他指出好的解决方案保持沉默就足够了,但这在我看来是不够的。@SteveP:最重要的是,关于掩蔽和位转移扮演什么角色,一分钱必须花掉。我已经给了OP一个答案,很容易看出这些元素是如何协同工作的。一旦他开始思考这个问题,他应该能够回到最初的解决方案,并做出决定当然。如果你不同意,那么请随意发布另一个解决方案。我很难过……因为你提出了这个解决方案,所以我已经毫无希望地困惑了,因为你提出了这个解决方案不用解释……谢谢杰瑞,这是一个很好的解释!:)你能检查一下我刚才做的工作吗?我做错了什么?
    upper4 | lowest2 | nextLowest2 = 0x12340000 | 0x00007800 | 0x00000056;
    
    int lower = X & 0x0000FFFF
    int upper = X & 0xffff0000;
    
    X                                                = 0x12345678
    lower                                            = 0x00005678
    (lower << 8)                                     = 0x00567800
    (lower >> 8)                                     = 0x00000056
    ((lower << 8) | (lower >> 8))                    = 0x00567856
    (0xFFFF & ((lower << 8) | (lower >> 8)))         = 0x00007856
    upper                                            = 0x12340000
    upper | (0xffff & ((lower << 8) | (lower >> 8))) = 0x12345678