在C中,如何有效地计算具有可变宽度类型的整数的汉明权重,例如, uint_fast8_t或uintmax_t?
注意:
答案 0 :(得分:4)
如何有效地计算具有可变宽度类型的整数的汉明权重,例如, uint_fast8_t或uintmax_t?
[...]
我正在使用GCC进行编译
我更喜欢使用__builtin_popcount()函数的解决方案
您可以根据相关类型if / else
撰写sizeof()
声明:
int weight(uintmax_t x) {
if (sizeof x <= sizeof int) {
return __builtin_popcount(x);
else if (sizeof x <= sizeof long) {
return __builtin_popcountl(x);
else {
return __builtin_popcountll(x);
}
}
GCC很有可能认识到关系表达式是编译时常量,因此优化所有这些只是调用适当的内置函数。
或者,您可以使用__builtin_popcountll(x)
;据我所知,GCC没有提供比long long int
更宽的整数类型,因此在所有情况下都会产生正确答案。
或者您可以确定在特定于机器的构建配置期间选择哪个替代方案(例如,通过Autoconf或CMake测试),并定义一个符号,指示GCC选择哪些可用的变体。此变体还允许您提供回退,以防您意外地遇到宽于long long int
的整数类型。
任何这些(除了后备)都可以让你通过一次调用合适的内置来计算汉明重量。我认为,与需要多次通话的替代方案相比,您更有效地表现出对高效性能的明显兴趣。
答案 1 :(得分:3)
假设有问题的类型是 unsigned :
获取有问题的数字,抓住低8位,转换为__builtin_popcount()
,然后转到int count_bits(some_type x)
{
int count = 0;
while (x > 0) {
count += __builtin_popcount((uint8_t)(x & 0xFF));
x >>= 8;
}
return count;
}
。向右移8位并重复直到你得到0。
\r
答案 2 :(得分:-1)
您不需要知道该数字中有多少位。你只需要知道什么时候没有设置。对于简单的无符号类型 - 它将为零。
this.controller.get('email)