2011-01-25 42 views
6

這是NVIDIA代表在職業博覽會上提出的一個問題:交換字節中的每一位

寫一個小而高效的代碼來交換字節內的每對位;例如,10 11 01 10應該變爲01 11 10 01

有沒有更「有效」的方法,這樣做比通過所有其他指數做for循環?我的代碼很小,但我想不出比循環更有效「,我猜可能有一種方法來使用XOR來避免循環,但是我不能想辦法。

謝謝!

+0

它`wasn't`一個問題嗎?我沒有看到它...... – 2011-01-25 00:31:29

+1

@MrDisappointment我懷疑如果這是一個問題,Mehrdad會違反書面協議或要求不要與他人分享這個問題。 – Phrogz 2011-01-25 00:34:31

+0

@MrDisappointment:LOL對不起,錯字;固定XD ... @Phrogs:沒有這樣的協議或任何東西,這是一個開放的職業公平,有一兩百人;沒有簽名或任何類型的東西。 :) – Mehrdad 2011-01-25 00:36:42

回答

11

你可以使用256條目查找表。

或者,((x & 0x55) << 1) | ((x & 0xAA) >> 1)

1

查表(除非有他一直在尋找一些特定的NVIDA特定的解決方案)。

+0

它並不是在尋找NVIDIA特定的解決方案,但它正在尋找快速*和*小代碼......表查找解決方案會計數嗎? (雖然我沒有想到它......) – Mehrdad 2011-01-25 00:33:28

+0

@Mehrdad:表查找只是一個「想到的第一件事」與這些類型的問題。當然可能會有更好,更聰明的一點。你也可以考慮使用一個較小的16字節(甚至可能是8字節)的表,並結合一些移位/掩碼操作來一次查找4位。我不確定最佳位置可能在哪裏。 – 2011-01-25 00:42:07

12

像這樣的事情應該由1位工作

(i >> 1) & 01010101 + (i << 1) & 10101010 

i >> 1轉變一切的權利,& 01010101在偶數位置只剩位。
第二部分涉及同一個fasion中的奇數位位置。

不知道如何有效的,雖然。

0

由於只有256字節中的可能的組合,這似乎是一個很好的候選,用於當連續執行速度比inital預先計算和/或總存儲器利用率更重要的使用基於查找表溶液的任何時間。

例如:

lookupTable[00000000] = 00000000 
lookupTable[00000001] = 00000010 
lookupTable[00000010] = 00000001 
... 
2

沒有查找表(或產生首位的事),你還可以:

  • 左移和,並與左位掩碼(10101010)
  • 右移AND右位掩碼(01010101)
  • OR結果一起。

左移是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的所有值(確保您的循環終止!)來生成你的「表」。

1

在Java中的32位整數..

public int swapOddEvenbits(int x) 
{ 
    return ( ((x & 0xaaaaaaaa) >> 1 | ((x & 0X55555555) << 1)); 

} 

如果您正在使用64位的工作,你需要改變面罩..