這是NVIDIA代表在職業博覽會上提出的一個問題:交換字節中的每一位
寫一個小而高效的代碼來交換字節內的每對位;例如,10 11 01 10
應該變爲01 11 10 01
。
有沒有更「有效」的方法,這樣做比通過所有其他指數做for
循環?我的代碼很小,但我想不出比循環更有效「,我猜可能有一種方法來使用XOR來避免循環,但是我不能想辦法。
謝謝!
這是NVIDIA代表在職業博覽會上提出的一個問題:交換字節中的每一位
寫一個小而高效的代碼來交換字節內的每對位;例如,10 11 01 10
應該變爲01 11 10 01
。
有沒有更「有效」的方法,這樣做比通過所有其他指數做for
循環?我的代碼很小,但我想不出比循環更有效「,我猜可能有一種方法來使用XOR來避免循環,但是我不能想辦法。
謝謝!
你可以使用256條目查找表。
或者,((x & 0x55) << 1) | ((x & 0xAA) >> 1)
。
查表(除非有他一直在尋找一些特定的NVIDA特定的解決方案)。
它並不是在尋找NVIDIA特定的解決方案,但它正在尋找快速*和*小代碼......表查找解決方案會計數嗎? (雖然我沒有想到它......) – Mehrdad 2011-01-25 00:33:28
@Mehrdad:表查找只是一個「想到的第一件事」與這些類型的問題。當然可能會有更好,更聰明的一點。你也可以考慮使用一個較小的16字節(甚至可能是8字節)的表,並結合一些移位/掩碼操作來一次查找4位。我不確定最佳位置可能在哪裏。 – 2011-01-25 00:42:07
像這樣的事情應該由1位工作
(i >> 1) & 01010101 + (i << 1) & 10101010
i >> 1
轉變一切的權利,& 01010101
在偶數位置只剩位。
第二部分涉及同一個fasion中的奇數位位置。
不知道如何有效的,雖然。
由於只有256字節中的可能的組合,這似乎是一個很好的候選,用於當連續執行速度比inital預先計算和/或總存儲器利用率更重要的使用基於查找表溶液的任何時間。
例如:
lookupTable[00000000] = 00000000
lookupTable[00000001] = 00000010
lookupTable[00000010] = 00000001
...
沒有查找表(或產生首位的事),你還可以:
左移是01 10 11 00 與10101010蒙面給了我們00 10 10 00
右移(原)是與01010101掩蓋給我們01 01 00 01
或我們的結果一起
所以在C或C++中,你可以做
unsigned char bitswap(unsigned char uch)
{
return ((uch<<1) & 0xAA) | (uch>>1) & 0x55);
}
只需運行從0x00到0xFF的所有值(確保您的循環終止!)來生成你的「表」。
在Java中的32位整數..
public int swapOddEvenbits(int x)
{
return ( ((x & 0xaaaaaaaa) >> 1 | ((x & 0X55555555) << 1));
}
如果您正在使用64位的工作,你需要改變面罩..
它`wasn't`一個問題嗎?我沒有看到它...... – 2011-01-25 00:31:29
@MrDisappointment我懷疑如果這是一個問題,Mehrdad會違反書面協議或要求不要與他人分享這個問題。 – Phrogz 2011-01-25 00:34:31
@MrDisappointment:LOL對不起,錯字;固定XD ... @Phrogs:沒有這樣的協議或任何東西,這是一個開放的職業公平,有一兩百人;沒有簽名或任何類型的東西。 :) – Mehrdad 2011-01-25 00:36:42