Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在二进制表示法中,一个数的奇偶位置的1的个数是多少?_C++_Performance_Binary_64 Bit_Bit Manipulation - Fatal编程技术网

C++ 在二进制表示法中,一个数的奇偶位置的1的个数是多少?

C++ 在二进制表示法中,一个数的奇偶位置的1的个数是多少?,c++,performance,binary,64-bit,bit-manipulation,C++,Performance,Binary,64 Bit,Bit Manipulation,无论是按位还是64位范围内整数的任何函数,它们都是实现它的更快的方法。除了我已经实现的方法 /* Find F(i)=abs(a(i)-b(i)) a(i)=number of 1's in even position b(i)=number of 1's in odd position for an integer i, where i fits in 64-bit */ //function calculate the above equation //returns the answ

无论是按位还是64位范围内整数的任何函数,它们都是实现它的更快的方法。除了我已经实现的方法

/* 
Find F(i)=abs(a(i)-b(i))
a(i)=number of 1's in even position 
b(i)=number of 1's in odd position 
for an integer i, where i fits in 64-bit
*/
//function calculate the above equation
//returns the answer
long long int F(long long int k)
{
    //size of array is taken for 64-bit number
    int a[64]={0},i,a,b;
    long long int m;
    m=k;
    //convert long long int into binary 
    for(i=63;i>-1;i--)
    {
        if(m==1||m==0)
        {
            a[i]=m;
            break;       //exit the for loop
        }
        a[i]=m%2;        //storing bit by bit
        m/=2;           
    }
    // initialized with a value of zero
    a=0;
    b=0;
    //find first bit having 1
    int f;
    for(i=0;i<64;i++)
    {
        if(a[i]==1)
        {
            f=i;
            break;
        }
    }
    //calculating the number of 1's in even and odd positions
    for(i=f;i<64;i++)
    {
        if(a[i]==1)
        {
            if((63-f)%2==0)
            {
                a++;          //1's in even positions
            }
            else
            {
                b++;          //1's in odd positions
            }
        }
    }

    //return the answer
    return abs(a-b);
}
所以基本上我要做的是,用mod 2的简单方法,转换二进制表示的整数。然后执行一项任务,以查找从左到右的二进制表示形式中的第一个1,指针位于第一个数字上。现在使用第一个1的索引计算奇偶位置的1的数量。最后返回奇偶位置1的绝对差值。

一种简单的方法:

#include <stdint.h>
int absdiffevenoddpopcount(uint64_t x) {
    uint64_t a = x &  0x5555555555555555;
    uint64_t b = x & ~0x5555555555555555;
    while(a && b) {
        a &= a - 1;
        b &= b - 1;
    }
    x = a ? a : b;
    int r = 0;
    while(x) {
        x &= x - 1;
        r++;
    }
    return r;
}
不管怎么说,本页收集了这些比特黑客:

此外,有些处理器有特殊指令,可能更快地进行位填充计数,通常编译器将其作为内置项提供给C。

一种简单的方法:

#include <stdint.h>
int absdiffevenoddpopcount(uint64_t x) {
    uint64_t a = x &  0x5555555555555555;
    uint64_t b = x & ~0x5555555555555555;
    while(a && b) {
        a &= a - 1;
        b &= b - 1;
    }
    x = a ? a : b;
    int r = 0;
    while(x) {
        x &= x - 1;
        r++;
    }
    return r;
}
不管怎么说,本页收集了这些比特黑客:


另外,有些处理器有一些特殊指令,这些指令可能会更快地进行位填充计数,通常编译器会将其作为内置项提供给C。

基本上,您可以使用它&只保留奇偶位。 您可以对这两个数字进行popcount,最后返回差值。 因此:


我用gcc bultin popcount写的。如果使用其他编译器,您可以在其手册中找到这一点。

基本上,您可以使用&只保留奇偶位。 您可以对这两个数字进行popcount,最后返回差值。 因此:


我用gcc bultin popcount写的。如果使用另一个编译器,你可以在手册中找到这个。

< P>一个更为C++的友好版本:

int F(long long const k) {
  return std::abs(static_cast<int>(std::bitset<64>(k & 0x5555555555555555).count()) - 
                  static_cast<int>(std::bitset<64>(k & 0xaaaaaaaaaaaaaaaa).count()));
}

一个更友好的C++版本:

int F(long long const k) {
  return std::abs(static_cast<int>(std::bitset<64>(k & 0x5555555555555555).count()) - 
                  static_cast<int>(std::bitset<64>(k & 0xaaaaaaaaaaaaaaaa).count()));
}


您的站点:为了快速实现,请使用二进制移位操作。@学习者:可能快一点,但bithacks页面仍然列出了更好的选项。@重复数据消除器:谢谢链接。您的站点:为了快速实现,请使用二进制移位操作。@Learner:可能快一点,但是bithacks页面仍然列出了更好的选项。@重复数据消除程序:感谢您的链接。那些666掩码来自何处?@harold:掩码错误,sry。请注意,为了提高性能,最好使用内置popcount,因为它可能映射到一条CPU指令。例如,在Intel上,自从Nehalem之后就有这样一条指令。@Deduplicator我只看到了您的原始代码。没有看到编辑。但你是对的:那666个掩码是从哪里来的?@harold:错误的掩码,sry。请注意,为了提高性能,最好使用内置的popcount,因为它可能映射到一条CPU指令。例如,在Intel上,自从Nehalem之后就有这样一条指令。@Deduplicator我只看到了您的原始代码。没有看到编辑。但你是对的:为什么你要把结果扩大到长期?popcount返回int,它有足够的范围,甚至可以很长很长。我拿了他原始的函数签名,也许他需要它长一些来做其他事情。为什么你要把结果扩大到长呢?popcount返回int,它有足够的范围,甚至可以很长很长。我拿了他原始的函数签名,也许他需要它长一些。