反向字节顺序为long

我有一个long变量,我需要反转它的字节顺序。 例如: B1, B2, ... , B8我应该返回一个由B8, B7, ..., B1组成的长B8, B7, ..., B1 。 如何通过使用按位运算来实现?

你可以使用Long.reverseBytes(长)

或者对于包含按位运算的更多方法,您可以参考此堆栈溢出问题

这是你可能喜欢的另一种方法,我仍然会推荐上述方法,但它比你在容易出错的位置更好。

字节缓冲区

 byte[] bytes = ByteBuffer.allocate(8).putLong(someLong).array(); for (int left = 0, right = bytes.length - 1; left < right; ++left, --right) { byte temp = bytes[left]; bytes[left] = bytes[right]; bytes[right] = temp; } 

我试图引导你远离按位解决方案,因为它们很麻烦,如果你不知道你在做什么就很容易陷入困境......但是按位看起来像这样:

 byte[] bytes = new byte[8]; // set the byte array from smallest to largest byte for(int i = 0; i < 8; ++i) { byte[i] = (your_long >> i*8) & 0xFF; } // build the new long from largest to smallest byte (reversed) long l = ((buf[0] & 0xFFL) << 56) | ((buf[1] & 0xFFL) << 48) | ((buf[2] & 0xFFL) << 40) | ((buf[3] & 0xFFL) << 32) | ((buf[4] & 0xFFL) << 24) | ((buf[5] & 0xFFL) << 16) | ((buf[6] & 0xFFL) << 8) | ((buf[7] & 0xFFL) << 0) ; 

您可能希望使用Long.reverseBytes而不是使用按位运算。 有关详细信息,请参阅Java参考 。

否则,您可以查看Long.java中的JDK源(JDK文件夹中的Long.java ),但请注意Oracle的版权。

这是一个老技巧,你可以使用endos交换寄存器:

 static long swapblock(long a, long mask, int shift) { long b1 = a & mask; // extract block long b2 = a ^ b1; // extract remaining bits return (b1 << shift) | ((b2 >> shift) & mask); // mask again to clear sign extension } static long endianswap(long a) { a = swapblock(a, 0x00000000ffffffffL, 32); a = swapblock(a, 0x0000ffff0000ffffL, 16); a = swapblock(a, 0x00ff00ff00ff00ffL, 8); return a; } 

我们的想法是逐步交换子块,直到达到想要停止的所需级别。 通过添加大小为4,2和1的交换,您可以将其更改为位镜像function。

由于缺少java中的无符号类型,因此只有一个棘手的问题。 您需要在向右移位时屏蔽高位,因为符号位由移位量复制,用1填充高位( 0x8000000000000000 >> 80xFF80000000000000 )。

 long reverse(long x){ x = (x >> 32) | (x << 32); // step 1 x = ((x & 0xffff0000ffff0000 ) >> 16) | ((x & 0x0000ffff0000ffff ) << 16); // step 2 x = ((x & 0xff00ff00ff00ff00 ) >> 8) | ((x & 0x00ff00ff00ff00ff ) << 8); // step 3 return x; } 

如果我们假设按位运算符在O(1)时间内工作,则反向函数在O(lg(位数))时间内工作。

说明
步骤0:B1 B2 B3 B4 B5 B6 B7 B8
步骤1:B5 B6 B7 B8 B1 B2 B3 B4
步骤2:B7 B8 B5 B6 B3 B4 B1 B2
步骤3:B8 B7 B6 B5 B4 B3 B2 B1

循环的简单回答:

 public static long byteReverse(long a) { long result = 0; for(int i = 0; i < 8; i++){ // grab the byte in the ith place long x = (a >> (i*8)) & (0b11111111); result <<= 8; result |= x; } return result; } 

仅按位:

 public static long byteReverse(long a) { a = (a << 32) | (a >>> 32); a = ((a & 0xffff0000ffff0000L) >>> 16) | ((a & 0x0000ffff0000ffffL) << 16); a = ((a & 0x00ff00ff00ff00ffL) << 8) | ((a & 0xff00ff00ff00ff00L) >>> 8); return a; }