我有一个long
变量,我需要颠倒它的字节顺序。例如:B1, B2, ... , B8
我应该返回一个包含B8, B7, ..., B1
的长整数。我怎样才能通过使用按位操作?反向字节长的顺序
Q
反向字节长的顺序
3
A
回答
6
或者更多的方法,其中包括按位运算,你可以参考这个stack overflow question
继承人另一个你可能喜欢的方式,我还是建议以上,但它比按位好你可以轻松地犯错误。
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) ;
2
您可能想要使用Long.reverseBytes
而不是按位操作。详细信息请参见Java Reference。
否则,您可以看看Long.java
中的JDK源文件(位于JDK文件夹中的src.zip),但请注意Oracle的版权。
1
这里是一个老把戏,你可以用它来交换尾段寄存器:
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的交换,您可以将其更改为位镜像功能。
由于缺少java中的无符号类型,只有一个棘手的问题。在向右移位时需要屏蔽高位,因为符号位被移位量复制,用高位位填充1(0x8000000000000000 >> 8
为0xFF80000000000000
)。
0
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
0
平原答案与循环:只有
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;
}
相关问题
- 1. 反向字节顺序
- 2. Delphi字节的反向顺序
- 3. 反向字节顺序登记
- 4. 反向字符串顺序
- 5. fwrite写入反向数字字节顺序
- 6. c中的字节反转顺序
- 7. ASCII IP到主机字节顺序长
- 8. ObservableCollection的反向顺序
- 9. 反向字符串列表顺序
- 10. R,GGPLOT2:反向字母顺序
- 11. 反向Python中的字符串在同一时间(网络字节顺序)
- 12. F# - 反向管道顺序
- 13. 反向输出顺序
- 14. 字符串反向顺序像“你好Word”反向在PHP中的“字你好”
- 15. “IBM PC”字节顺序的字节顺序?
- 16. 网络字节顺序来承载java中的字节顺序
- 17. 混淆网络字节顺序和主机字节顺序
- 18. 网络字节顺序来承载字节顺序转换Java
- 19. 的NSArray和字节顺序
- 20. “反向” 的NSMutableArray的元素顺序
- 21. iOS反向tableView排序顺序
- 22. 的Python:反向顺序列表
- 23. SQL查询输出的反向顺序
- 24. 堆栈元素的反向顺序
- 25. 文章的反向日期顺序PHP
- 26. THREE.js中的反向顶点顺序
- 27. 旋转矩阵的反向顺序
- 28. ggplot2:时间日期的反向顺序
- 29. 脚本中的反向日期顺序
- 30. PHP获取数组的反向顺序
你在使用endian-ness吗? – 2012-04-21 14:44:35