我想通過獲得第一非0 byte
在int
您的意思是int
的自然8位中斷,而不是動態的8位中斷。
自然8位符:
00000000
|
00010110
|
10110010
|
11110001
==>00010110
動態8位突破:
00000000000
|
10110101
|
1001011110001
==>10110101
這將返回上int
的自然8位斷裂第一非零byte
沒有循環或支化。此代碼可能會或可能不會更有效,然後paulsm4
的答案。請務必對代碼進行基準測試和/或分析,以確定哪種方法最適合您。
Java代碼:ideone link
class Main {
public static void main(String[] args) {
int i,j;
for (i=0,j=1; i<32; ++i,j<<=1) {
System.out.printf("0x%08x : 0x%02x\n",j,getByte(j));
}
}
public static byte getByte(int n) {
int x = n;
x |= (x >>> 1);
x |= (x >>> 2);
x |= (x >>> 4);
x |= (x >>> 8);
x |= (x >>> 16);
x -= ((x >>> 1) & 0x55555555);
x = (((x >>> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >>> 4) + x) & 0x0f0f0f0f);
x += (x >>> 8);
x += (x >>> 16);
x &= 0x0000003f;
x = 32 - x; // x now equals the number of leading zeros
x &= 0x00000038; // mask out last 3 bits (cause natural byte break)
return (byte)((n&(0xFF000000>>>x))>>>(24-x));
}
}
爲什麼是while循環的問題嗎?無論如何,這裏只有四個字節,所以你可以寫下四個明確的步驟。 – Thilo
如果我可以在沒有for循環的情況下執行相同的操作,它將會少於運行時指令。這不是瓶頸,但儘管如此,它仍然很高興知道。 – Brad
您的工具鏈可能會提供直接映射到快速硬件指令的「計數前導零」內在值,例如, __builtin_clz()在gcc中。一旦你有numzeros = clz(n),你可以用(((unsigned int)n)>>((sizeof(int) - (numzeros/8))* 8))&0xff這樣的代碼來提取字節, -zero n。請注意,負數的右移會在C中調用未定義的行爲,因此將轉換爲unsigned int。類似地,等於操作數大小的移位量導致未定義的行爲,這就是n不能爲零的原因。 – njuffa