如何交换前两个连续的不同位

How to swap first 2 consecutive different bits

本文关键字:连续 两个 何交换 交换      更新时间:2023-10-16

在无符号整数中交换前两个(最低有效位)不同连续位的快速而优雅的方法是什么?

例如

100100 -> 100010
110011 -> 110101

到目前为止,我想出了这个:

unsigned long long special_swap(unsigned long long number)
{
    if (number & 1)
        return (number + 1) ^ ((number ^ (number + 1)) >> 2);
    number = ~number;
    return ~((number + 1) ^ ((number ^ (number + 1)) >> 2));
}

我对上述解决方案最大的不满是它使用了if指令。

我会这样做:

unsigned long long my_swap(unsigned long long number)
{
 unsigned long long x = number ^ (number >> 1);
 return number ^ ((x & -x) * 3);
}

当数字==0时,我的解决方案返回0,而原始问题的函数返回110000000000000000000000000000000000000000000000000000000000000000000。

一些解释:如果这个位置的比特等于下一个比特,则x的比特包含0,如果不同,则包含1。(x&-x)是x的最低有效位,也就是说第一个位差。

在不使用if的情况下,这是相同的想法。

unsigned long long special_swap(unsigned long long number)
{
    unsigned long long t = ((number & 1) << 1) - 1;
    return (number + t) ^ ((number ^ (number + t)) >> 2);
}

变量t是1或-1,具体取决于数字的lsb。

实时测试