从二进制数中提取ODD数字的最佳方法

时间:2015-06-16 02:20:20

标签: algorithm bit-manipulation

给定64位数字,我需要从中提取每一位,并将其转换为数字:

decimal:  357
binary:   0000 0001 0110 0101
odd bits:  0 0  0 1  1 0  1 1
decimal:  27

有什么好的算法方法吗?不,不是HW,这适用于现实世界:)

4 个答案:

答案 0 :(得分:5)

我会一次两个执行算术右移(直到二进制数的长度)。我的逻辑中使用的>>用于算术移位。

  

(注意:在C语言中,右移可能是也可能不是算术!)

喜欢,

int count=0;
bit=extractLastbit(binary_representation_of_the_number);

while(count!=binaryLength){
  // binaryLength is the length of the binary_representation_of_the_number
  binary_representation_of_the_number=binary_representation_of_the_number>>2;

  bit.appendLeft(extractLastbit(binary_representation_of_the_number);
  count=count+2;
}

其中,

extractLastBit()提取二进制数的LSB; appendLeft()执行将新提取的位移位到较旧位的左侧。

答案 1 :(得分:3)

创建一个包含256个条目的表来查找每个字节。表中的条目值将转换为数字。然后将4个字节与移位一起粘贴以得出最终数字。

这是一个缩小范围的示例,以便您了解相关信息。 查找部分使用4位而不是8:

0000 = 00
0001 = 01
0010 = 00
0011 = 01
0100 = 10
0101 = 11
...

抬头说01010010。分成010​​1和0010.看看我们得到的那些 11,和00粘贴在一起:1100

使用256表,您需要进行8次查找以及相应的粘贴。如果你有2 ** 16个条目的内存,那么你只需要进行四次查找,并且粘贴也会相应减少。

该表不具有2的均匀功率。例如,有1024个条目(2 ** 10),有7个查找。当表指数恰好是2的幂(2,4,8,16或32)时,只有经济。

答案 2 :(得分:3)

How to de-interleave bits (UnMortonizing?)

x = x& 0x5555555555555555; //restrict to odd bits.
x = (x | (x >> 1)) & 0x3333333333333333;
x = (x | (x >> 2)) & 0x0f0f0f0f0f0f0f0f;
x = (x | (x >> 4)) & 0x00ff00ff00ff00ff;
x = (x | (x >> 8)) & 0x0000ffff0000ffff;
x = (x | (x >>16)) & 0x00000000ffffffff;

答案 3 :(得分:-1)

这是我最终想到的 - 每个ODD位从/到X值,每个偶数位 - 从/到Y.我必须用JavaScript编写它。

function xyToIndex(x, y) {
    // Convert x,y into a single integer with alternating bits
    var mult = 1, result = 0;
    while (x || y) {
        result += (mult * (x % 2));
        x = Math.floor(x / 2);
        mult *= 2;
        result += (mult * (y % 2));
        y = Math.floor(y / 2);
        mult *= 2;
    }
    return result;
}

function indexToXY(index) {
    // Convert a single integer into the x,y coordinates
    // Given a 64bit integer, extract every odd/even bit into two 32bit values
    var x = 0, y = 0, mult = 1;
    while (index) {
        x += mult * (index % 2);
        index = Math.floor(index / 2);
        y += mult * (index % 2);
        index = Math.floor(index / 2);
        mult *= 2;
    }
    return [x, y];
}