2011-01-25 63 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位的工作,你需要改变面罩..