0

我有一个 8 uint64_t (512 位)的数组。我还收到 2 个数字作为函数参数。让它们分别为 54 和 133。我需要用低于 54 或高于 133 的位置(从零开始)屏蔽掉每一位。

最经济有效的方法是什么?

使用一个 uint64_t 很容易做到这一点。

int a=6;
int b=12;
uint64_t source=0xD0400000000000;
uint64_t mask=0xFFFFFFFFFFFFFFFF;
uint64_t result=source&((mask<<(a+63-b))>>a);//D0000000000000

但是大于 uint64_t 的数据(在本例中为数组)存在问题。另外,另一个问题是当我想提取多个 uint64_t 的跨边界时。
这段代码必须非常快,所以我必须避免分支或任何昂贵的操作。

有没有办法用内在函数来实现它以使其快速执行?

4

1 回答 1

0

Whether you like it or not, you'll need special handling for the first and the last array element involved, with if. Basically, you have to convert your first and last into bit-number/array index pairs, and work from there. To mask out everything but the designated range, you zap everything beloe the first array index, and after the last (probably using std::fill), and special handle the elements at the first and last array index (which may be the same, which in turn entails special handling, different from the case where they are different). Very roughly (and without any error handling):

//  quot is element index,
//  rem is bit number in element.
div_t first = div( firstBitNumber, bitsInWord );
div_t last = div( lastBitNumber, bitsInWord );
std::fill( array.begin(), array.begin() + first.quot, 0 );
if ( first.quot == last.quot ) {
    array[ first.quot ] &= ((1 << last.rem) - 1) & ~((i << first.rem) - 1);
} else {
    array[ first.quot ] &= ~((i << first.rem) - 1);
    array[ last.quot ] &= ((1 << last.rem) - 1);
}
std::fill( array.begin() + last.quot + 1, array.end(), 0 );

You'll probably need some casts with the shift operators, in order to ensure they use the full size of the array elements. And of course, you definitely want to ensure that first and last are in bounds before any of this.

于 2013-10-22T10:16:05.003 回答