将整数矩阵转换为bitstring?

时间:2015-11-28 18:01:01

标签: matrix bit-manipulation

我有一个4x4整数矩阵(称为tb),我可以从int64_t位串(称为state)创建,如下所示:

for(int i = 0; i < 4; i++) {
    for(int j = 0; j < 4; j++) {
        ipos -= 1;
        tb[i][j] = (state >> (4*_pos)) & 0xf);
    }   
}

然而,一旦我开始使用矩阵,我怎样才能将其更改为位串?我希望通过整数矩阵,获取元素,创建它的4位十六进制表示,然后将其移位(<<4)正确的次数和按位或(|) bitstring与新的state位串,但我不知道如何做到这一点,或者它是否是最好的方法。想法?

1 个答案:

答案 0 :(得分:1)

当然,就像你说的那样,就像这样(未经测试)

for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
        pos--;
        state |= (uint64_t)tb[i][j] << (4 * pos);
    }   
}

这有一个相当长的依赖链,这并不是特别好,如果你在HPC。你可以把它分成几部分,比如前半部分和后半部分,然后将它们组合在一起。作为奖励,这意味着轮班在32位而不是64位上运行,这在某些平台上可能更快。

根据tb的类型,可能还有其他技巧,例如,如果每个条目都是一个字节,并且您可以用两个uint64_t替换它,那么您可以使用直接组合条目行位操作(尽管与最方便的顺序相比它们是“反转的”)。

例如,可能是这样的(未经测试)(这假设订购相反,也可以使用相同的订单完成)

uint64_t low, high; // inputs
uint64_t even = 0x00FF00FF00FF00FFULL;
uint64_t odd = ~even;
low = (low & even) | ((low & odd) >> 4);
high = (high & even) | ((high & odd) >> 4);
even = 0x0000FFFF0000FFFFULL;
odd = ~even;
low = (low & even) | ((low & odd) >> 8);
high = (high & even) | ((high & odd) >> 8);
low = (low & 0xFFFF) | (low >> 16);
high = (high & 0xFFFF) | (high >> 16);
return low | (high << 32);

如果您允许特殊说明,则有更短的方式,(未经测试,并再次撤销订单)

low = _pext_u64(low, 0x0F0F0F0F0F0F0F0FULL);
high = _pext_u64(high, 0x0F0F0F0F0F0F0F0FULL);
return low | (high << 32);

相反的转换方式同样简单,

low = _pdep_u64(bitstring & 0xFFFFFFFF, 0x0F0F0F0F0F0F0F0FULL);
high = _pdep_u64(bitstring >> 32, 0x0F0F0F0F0F0F0F0FULL);

如果您只是首先反转半字节,这两个也适用于反转顺序,这也可以通过bitmanipulation完成。