[英]Can I play audio in reverse by writing AMR data bytes in reverse order?
[英]Reverse bytes order of 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的版權。
這是一個老技巧,你可以使用它來交換寄存器:
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
)。
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.