【问题标题】:Swap every two bits of an unknown variable type交换未知变量类型的每两位
【发布时间】:2013-09-27 02:03:26
【问题描述】:

我需要交换每两个相邻的位作为通用操作,这将对给定的每个变量类型都这样做。

我想到了每个字节所需的掩码和操作:

(var & 0x55) << 1 | (var & 0xAA) >> 1

但是我如何使它适用于假设一个整数? 我是否需要使用上述掩码创建一个sizeof(int)unsigned chars 数组并以这种方式应用操作?

【问题讨论】:

  • 所以 01101100 会变成 10011100?
  • 是的,正是@LoganMurphy
  • @LoganMurphy“每两个相邻位交换一次”,我认为是的。

标签: c bit-manipulation bit generic-programming


【解决方案1】:

您可以逐个字节地执行此操作(与逐个字符的字符相同)。

例如:

int n = 0xAA55A55A;
unsigned char *p = (unsigned char *) &n;

for (; p < (unsigned char *) &n + sizeof(n); p++)
   *p = (*p & 0x55) << 1 | (*p & 0xAA) >> 1;

【讨论】:

  • 没问题,当你发布代码时总是使用 Code Sample 按钮,那个看起来像两个花括号 { }
  • 我很难理解你的例子。你在哪里使用ni 是什么?
  • No.. 实际上n 是一个错字;)
  • @Quaker 后者。所以它基本上是在n的每个字节上运行的
【解决方案2】:

两个建议: 您可以使用 256 个字符的查找表,而不是使用逻辑操作。:

char lookUpTable[256] = {0x00, 0x02, 0x01 ...};

如果您不想静态初始化此查找,您可以编写一个使用逻辑操作对其进行初始化的函数。

当你想交换字节 b 时,你要么简单地编写 lookUpTable[b],要么用一个函数包装它。

至于交换任何类型,你编写一个函数来做类似的事情:

void SwapBits(char* data, size_t len)
{
    For (; len > 0; len--)
    {
        *data = lookUpTable[*data];
        data++;
    }
}

然后你可以这样使用:

AnyType swapMe = whatever;
SwapBits((char*)(&swapMe), sizeof(AnyType));

注意这替换了 swapMe 的“内容”。

还有一件事,右移行为是特定于架构的,某些架构可能会在右移时进行符号扩展。使用如下表达式会更通用:

SwappedByte = ((Byte >> 1)&0x55) | ((Byte << 1)&0xaa)

通过这种方式,您可以删除任何符号扩展工件。

【讨论】:

    【解决方案3】:

    类似的东西。将任何变量的地址转换为 char *,您可以遍历字节。

    #include <stdio.h>
    
    char swap_c(char);
    void swap_r(char *, int);
    
    int main(void) {
        char c = 10;
        c = swap_c(c);
        printf("%i\n", c);
        int i = 10;
        char * r = (char *) &i; //you can cast the address of any variable into a char *
        swap_r(r, sizeof(int));
        printf("%i\n", i);
    }
    
    void swap_r(char * c, int length) {
        int i = 0;
        while(i < length) {
            c[i] = swap_c(c[i]);
            i++;
        }       
    }
    
    char swap_c(char c) {
        return (c & 0x55) << 1 | (c & 0xAA) >> 1;
    }
    
    //1010
    //0101
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多