我想在C中使用128位无符号整数。我编写了以下代码:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include <stdint.h>
#include <limits.h>
#define unt __uint128_t
#define G1 226854911280625642308916404954512140970
int countSetBits(unt n){
int count = 0;
while(n){ n &= (n-1) ; count++; }
return count;
}
int main(){
printf(" %d\n",countSetBits(G1) );
}
尽管输出应该是64,但G1的位数是96。我使用gcc编译器。我知道GMP GNU,但是出于我的目的,我需要快速执行。因此,我想避免使用GNU库。
答案 0 :(得分:3)
由于问题here得到了解释,因此您需要使用两个64位值来分配常量:
#include <stdio.h>
#define uint128_t __uint128_t
#define G1 ((uint128_t)12297829382473034410 << 64 | (uint128_t)12297829382473034410)
int countSetBits(uint128_t n) {
int count = 0;
while(n) {
n &= (n - 1);
count++;
}
return count;
}
int main() {
printf(" %d\n",countSetBits(G1) );
}
输出:
64
onlinegdb中提供了实时版本。
答案 1 :(得分:2)
C语言中没有128个常量,因此您需要使用两个64位值并将它们组合起来
#define unt __uint128_t
#define G1 ((((__uint128_t)0xaaaaaaaaaaaaaaaaull) << 64) + ((__uint128_t)0xaaaaaaaaaaaaaaaaull))
int countSetBits(unt n){
int count = 0;
while(n){ n &= (n-1) ; count++; }
return count;
}
int countSetBits1(unt n){
int count = 0;
while(n)
{
count += n & 1;
n >>= 1;
}
return count;
}
int main(){
printf(" %d\n",countSetBits(G1) );
printf(" %d\n",countSetBits1(G1) );
}
答案 2 :(得分:2)
由于您使用的是一个gcc扩展名,因此我认为还可以。 gcc具有一系列内部函数,用于返回常规整数类型中的设置位数。根据您的CPU和gcc选项,这将成为适当的指令,或者退回到调用库函数。
类似的东西:
int bitcount_u128(unsigned __int128 n) {
uint64_t parts[2];
memcpy(parts, &n, sizeof n);
return __builtin_popcountll(parts[0]) + __builtin_popcountll(parts[1]);
}
如果将x86处理器与popcnt
指令一起使用(最近十年制造最多),请使用-mpopcnt
或适当的-march=
设置进行编译以使用硬件指令。 / p>
或者,如果您可以将支持仅限于具有popcnt
的x86处理器,则可以使用_mm_popcnt_u64()
中的<nmmintrin.h>
内在函数来代替__builtin_popcountll()
。