【发布时间】:2019-07-12 06:30:02
【问题描述】:
我正在编写一个 C++ 程序,并且需要一个在所有现有 '1' 之后将所有 9 位设置为 1 的函数。
也就是说,我要编写一个函数void set10BitsFull(int64_t& n),它对于整数“int64_t n = 0b...1000000000...”,set10BitsFull(n) 将n 转换为“0b...1111111111...”。
(更新)输入整数的位被稀疏设置为 1,并且两个 1 之间至少有 10 位距离。对于样本输入0x20000200,预期输出为0x3FF003FF。在最后一个 1 之后至少会有 9 位 0。最左边的 10 位将始终为零。
这是我对这个函数的实现
/**
* Inline function that set 10 bits to 1 after each set 1
* i.e.,
* ......1000000000...... -> ......1111111111.......
*
* @param n
* pointer of input number
*/
inline void set10BitFull(int_fast64_t *n) {
// n = 1000000000
*n |= (*n >> 1); // n = 1100000000
*n |= (*n >> 2) | (*n >> 4) | (*n >> 6) | (*n >> 8); // n = 1111111111
}
在程序的主循环中,这两行代码会被频繁调用,在之前的测试中,计算成本非常高。因此,我想寻求一种计算开销更少(计算的 cpu 周期更少)的方法,可能的解决方案可能包括:
- 使用预先计算的掩码
- 内联汇编
- x86/gcc 内置内在 ...
【问题讨论】:
-
您的问题需要对预期输出与输入的比较进行一些改进。 “在所有 1 之后设置 9 位”没有多大意义。你能澄清一下吗?否则,我想知道为什么您的实现不是
n = n | 0x1ff -
您希望每个位都向右复制 9 次?如果输入是
0b100怎么办?如果输入是0b1001001001001001001怎么办?等等。正如其他人所提到的,您需要更好地定义您想要实现的目标。 -
另外:对有符号整数类型进行位移时要小心。 Implementation defined and even undefined behavior are just around the corner。您可能应该使用无符号整数类型。
-
@selbie:“在每个设置 1 之后将 10 位设置为 1 的内联函数”。这对我来说很清楚。
-
@Federico :操作员要求一种优化的方法来做某事。准确了解预期的行为将对此有很大帮助。例如,也许提到的一些可能的输入是永远不可能的。也许只有一个位设置。也许这种行为并不完全是你所理解的。任何这些知识都可以提供一种更快的方法。
标签: c++ bit-manipulation