C语言 交换给定整数中的两位

hl0ma9xz  于 2023-02-11  发布在  其他
关注(0)|答案(6)|浏览(106)

我看到了一些解决方案,但看起来很复杂。
在n,m位置的两个位之间交换的最有效方法是什么?

int swapBits(int num, int nPostion, int mPosition);
cgvd09ve

cgvd09ve1#

给定整数n,我们希望在其中交换位置p1和p2处的位:算法:如果两个位相同,则仅返回相同的值,否则使用XOR来切换两个位。

unsigned int swapBits(unsigned int n, unsigned int p1, unsigned int p2)
{
  return (((n >> p1) & 1) == ((n >> p2) & 1) ? n : ((n ^ (1 << p2)) ^ (1 << p1)));
}
vwkv1x7d

vwkv1x7d2#

不确定这是最有效的,但我认为这是一个相当简单的解决方案:

int bitValue(int num, int nPosition)
{
    return ( num >> nPosition ) % 2;
}

int swapBits(int num, int nPosition, int mPosition)
{
    int nVal = bitValue(num, nPosition);
    int mVal = bitValue(num, mPosition);

    if (nVal != mVal)
    {
        if (1 == nVal)
        {
           num -= 1<<nPosition;
           num += 1<<mPosition;
        }
        else
        {
            num += 1<<nPosition;
            num -= 1<<mPosition;
        }
    }

    return num;
}

以更高效(但可读性较差)的方式提供相同的解决方案:

int swapBits2(int num, int nPosition, int mPosition)
{
    int nVal = ( num >> nPosition ) % 2;
    int mVal = ( num >> mPosition ) % 2;

    if (nVal != mVal)
    {
        num += (-1)*(2*mVal-1)*(1<<mPosition) + (-1)*(2*nVal-1)*(1<<nPosition);
    }

    return num;
}

最后:

int swapBits3(int num, int nPosition, int mPosition)
{
    int k = ((num >> nPosition) & 1) - (num >> mPosition) & 1;

    return num + k*(1<<mPosition) - k*(1<<nPosition);
}
50few1ms

50few1ms3#

帕斯贝拉的答案包含了一个分支,但异或思想是正确的。
假设p的位为????A????B???,要将A变为B,将B变为A,我们需要将它们与(A^B)进行异或,为方便起见,设X=A^B

????A????B???
0000X0000X000 ^
=============
????B????A???

我们如何生成0000X0000X000

????A????B???    >> (nPostion-mPostion)
?????????A???    ^
?????????X???    & (1<<mPosition)
000000000X000    << (nPostion-mPostion)
0000X00000000    +
0000X0000X000    ^
????A????B???    ==
????B????A???
tuwxkamq

tuwxkamq4#

您可以使用以下宏来避免临时变量或堆栈分配,并且它将适用于任何数值类型:

#define SWAP_BITS(v,b1,b2) \
    (((v)>>(b1)&1)==((v)>>(b2)&1)?(v):(v^(1ULL<<(b1))^(1ULL<<(b2))))
u2nhd7ah

u2nhd7ah5#

基于Shay Gold的解决方案,下面是一个修复了一些bug的解决方案:

unsigned int swapBits(unsigned int num, int nPosition, int mPosition) {
    unsigned int k = ((num >> nPosition) & 1) - ((num >> mPosition) & 1);
    return num + k * ((1U << mPosition) - (1U << nPosition));
}
ql3eal8s

ql3eal8s6#

unsigned int swapbits(unsigned int num, unsigned int pos1, unsigned int pos2) {
    unsigned int bits_of_interest_mask = (1 << pos1) | (1 << pos2);
    unsigned int bits_of_interest = num & bits_of_interest_mask;
    unsigned int null_factor = ((bits_of_interest != 0) & (bits_of_interest != bits_of_interest_mask));
    unsigned int xor_mask = null_factor * bits_of_interest_mask;
    return num ^ xor_mask;
}

(编译器删除了布尔乘法:第一个电子0f1x,第一个电子1f1x)

相关问题