如何计算为128位整数设置的位数

时间:2018-09-15 19:24:48

标签: c

我想在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库。

3 个答案:

答案 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()