我有一个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的交叉边界时 这段代码必须非常快,所以我必须避免分支或任何昂贵的操作。
有没有办法用内在函数实现它以使其快速执行?
答案 0 :(得分:0)
无论你喜欢与否,你都需要特殊处理
第一个和最后一个数组元素,if
。
基本上,你必须将你的第一个和最后一个转换为
位数/数组索引对,并从那里开始工作。掩盖
除了指定范围之外的所有东西,你都可以将所有东西都扯掉
第一个数组索引,并在最后一个(可能使用
std::fill
),并特别处理第一个和第二个元素
最后一个数组索引(可能是相同的,这反过来又需要
特殊处理,与它们的情况不同
不同)。非常粗略(并且没有任何错误处理):
// 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 );
您可能需要使用移位运算符进行一些转换 为了确保它们使用数组元素的完整大小。 当然,你绝对想要确保第一个和最后一个 在任何此之前都处于界限之内。