C中的位重排/操作

时间:2015-11-23 05:52:54

标签: c bit-manipulation byte lookup-tables bitmask

我想在一个字节中排列位,以产生一定的顺序。例如,如果起始字节如下0 1 1 0 1 0 1 0,其位标记为1 2 3 4 5 6 7 8,我想将其排列为符合以下定位:2 4 3 5 7 1 8 6结果为:1 0 1 1 1 0 0 0.最有效的方法是什么?我读到了#34;查找"表但我不确定这是如何工作的。有人可以给出一个例子,并解释一下在C中进行这种位重排的有效方法。

3 个答案:

答案 0 :(得分:3)

你可以创建一个" unsigned char"有256个条目。该数组的索引将是要转换的字节的当前值,该条目的值将是"转换的"值。

或者,您可以使用位掩码,"如果"陈述......但效率会降低。

这是"数组"的片段。方法...只定义了几个值... ...并且没有输出"二进制文本"格式。

#include<stdio.h>

unsigned char lkup[256] =
    { 0x00,            /* idx: 0  (0x00) */
      0x02,            /* idx: 1  (0x01) (0b00000001) */
      0x08,            /* idx: 2  (0x02) (0b00000010) */
      0x0a,            /* idx: 3  (0x03) (0b00000011) */
      0x01             /* idx: 4  (0x04) (0b00000100) */
      };

int main(int argc, char **argv)
{
    unsigned char wk = 3;

    printf("Input: %u  output: >%u\n", wk, lkup[wk]);
}

答案 1 :(得分:2)

我想我理解他想要实现的目标。此代码可以帮助您:

#include <stdio.h>
#include <stdint.h>

int main(void) {
  uint8_t original = 0b01101010;
  uint8_t positions[8] = {1,3,2,4,6,0,7,5};
  uint8_t result = 0;

  for(int i = 0; i < 8; i++)
  {   
     if(original & (1 << (7 - positions[i])))
        result |= (1 << (7-i));
  }
 return 0;
}

我做的第一件事是创建一个表示原始值的字节以及要更改的位置数组。下一步是查看xth处的原始字节。 position是零或一,然后移动结果中的值,如果是这样的话。最后一个for循环仅用于打印结果。 我将您的指数调整为从零开始。

答案 2 :(得分:0)

这是改变位位置的一种方法。使用&(和 - 运算符),我们从char中选择某些位,然后将它们移到新的位位置。最后,所有移位的位将由|(或 - 运算符)愉快地连接在一起。 左移<<将向左和向右移动位>>向右移动。我冒昧地重新编号位置。 7表示左侧最高有效位,0表示最低有效位,因此左右移位操作描述了正确移位方向。

为什么首先是移位操作然后是最后两行的AND操作? - 因为char-type可以是无符号的,如果我们对负值进行右移,例如11111000( - 8),则最高位将被复制; 11111000 >> 2会产生(1 filled from this end -->) 11111110( - 2)。 (见Right shifting negative numbers in C。)

但回到功能:

char changebitpositions (char ch) {

                                  // bit locations (- = don't care)
                                  // before      after
    return (ch & 0x20)            // --5----- => --5----- (no change)
        | ((ch & 0x49) << 1)      // -6--3--0 => 6--3--0-
        | ((ch & 0x12) << 2)      // ---4--1- => -4--1---
        | ((ch >> 5) & 0x04)      // 7------- => -----7--
        | ((ch >> 2) & 0x01);     // -----2-- => -------2

        // original and result:      76543210 => 64531702
}