用于生成下一位以在灰色代码中翻转的C代码

时间:2015-12-12 04:40:32

标签: c bit-manipulation

我需要一个函数,它返回一个数字,基本上告诉我在移动到格雷码的第n个元素时哪个位是要翻转的。如果它是标准(反射)格雷码或其他一些最小位切换方法并不重要。我可以做到,但似乎不必要地笨拙。目前我有这个:

#include <stdio.h>

int main()
{
        int i;
        for (i=1; i<32; i++)
                printf("%d\n",grayBitToFlip(i));
}


int grayBitToFlip(int n)
{
        int j, d, n1, n2;

        n1 = (n-1)^((n-1)>>1);
        n2 = n^(n>>1);
        d = n1^n2;
        j = 0;
        while (d >>= 1)
                j++;
        return j;
}

main()中的循环仅用于演示函数的输出。

有更好的方法吗?

编辑:只看输出,很明显可以更简单地做到这一点。我添加了第二个函数gray2,它可以更简单地完成相同的操作。这会是这样做的吗?这不是生产代码,而是业余爱好者。

#include <stdio.h>

int main()
{
        int i;
        for (i=1; i<32; i++)
                printf("%d  %d\n",grayBitToFlip(i), gray2(i));
}


int grayBitToFlip(int n)
{
        int j, d, n1, n2;

        n1 = (n-1)^((n-1)>>1);
        n2 = n^(n>>1);
        d = n1^n2;
        j = 0;
        while (d >>= 1)
                j++;
        return j;
}

int gray2(int n)
{
        int j;
        j=0;
        while (n)
                {
                if (n & 1)
                        return j;
                n >>= 1;
                j++;
                }
        return j;
}

1 个答案:

答案 0 :(得分:1)

最简单的格雷码是Johnson Gray Code(JGC)。

BitNumberToFlip = ++BitNumberToFlip  % NumberOfBitsInCode;

JGC = JGC ^ (1 << BitNumberToFlip);         // start JGC = 0;

Johnson代码表示所需的位数是线性的 二进制反射格雷码(BRGC)具有更好的位密度,因为只有 需要对数位数来表示BRGC代码的范围。

int powerOf2(int n){ return          //   does 16 bit codes
           ( n & 0xFF00 ? 8:0 )  +   //    88888888........
           ( n & 0xF0F0 ? 4:0 )  +   //    4444....4444....
           ( n & 0xCCCC ? 2:0 )  +   //    22..22..22..22..
           ( n & 0xAAAA ? 1:0 )  ; } //    1.1.1.1.1.1.1.1.
                           // much faster algorithms exist see ref.

int BRGC(int gc){ return (gc ^ gc>>1);} 

int bitToFlip(int n){ return powerOf2( BRGC( n ) ^ BRGC( n+1 ) ); }

详情见ref:
How do I find next bit to change in a Gray code in constant time?