简体   繁体   English

C中的位重排/操作

[英]Bit rearrangement/manipulation in C

I want to arrange bits in a byte, to result in a certain order. 我想在一个字节中排列位,以产生一定的顺序。 For example, if the starting byte is as follows 0 1 1 0 1 0 1 0 with bits labeled as 1 2 3 4 5 6 7 8, I want to arrange it so it matches the following positioning: 2 4 3 5 7 1 8 6 this results to: 1 0 1 1 1 0 0 0. What would be the most efficient way of doing so? 例如,如果起始字节如下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.最有效的方法是什么? I read about "look-up" tables but I am not sure how this works. 我读到了“查找”表,但我不确定这是如何工作的。 Can someone give an example and an explanation of an efficient way of doing this bit rearrangement in C. 有人可以给出一个例子,并解释在C中进行这种位重排的有效方法。

You could create an array of "unsigned char" with 256 entries. 您可以创建一个包含256个条目的“unsigned char”数组。 The index into that array would be the current value of the byte to be converted, and the value at that entry would be the "converted" value. 该数组的索引将是要转换的字节的当前值,该条目的值将是“转换”值。

Alternatively, you could use bit masking, and "if" statements... but it would less efficient. 或者,您可以使用位掩码和“if”语句......但效率会降低。

Here's a snippet of the "array" method... with only a few values defined... ... and no output of the output in "binary-text" format. 这是“数组”方法的片段......只定义了几个值......并且没有输出“二进制文本”格式的输出。

#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]);
}

I think I understood what he wants to achieve. 我想我明白了他想要实现的目标。 This code may help you: 此代码可以帮助您:

#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;
}

The first thing I have done is to create a byte that represents the original value as well as a array of the positions you want to change. 我做的第一件事是创建一个表示原始值的字节以及要更改的位置数组。 Next step ist to look the original byte at the xth. 下一步是查看xth处的原始字节。 position is zero or one and then shift the value in the result if so. position是零或一,然后移动结果中的值,如果是这样的话。 The last for-loop is just for printing the result. 最后一个for循环仅用于打印结果。 I adjusted your indices to be zero-based. 我将您的指数调整为从零开始。

Here is one way to change bit-positions. 这是改变位位置的一种方法。 With & (and-operator) we select certain bits from the char and then shift them to new bit-positions. 使用& (和 - 运算符),我们从char中选择某些位,然后将它们移到新的位位置。 Finally all the shifted bits will happily join together by | 最后,所有移位的位将通过|愉快地连接在一起 (or-operator). (或运营商)。 The left shift << will move bits left and right shift >> to the right. 左移<<将左右移位>>向右移动。 I took the freedom to renumber bit-positions. 我冒昧地重新编号位置。 7 means most-significant bit on the left and 0 is least-significant bit, so the left and right shift operations descripts shifting direction correctly. 7表示左侧最高有效位,0表示最低有效位,因此左右移位操作正确描述了移位方向。

And why there is the shift operations first and then AND-operation for the last two rows? 为什么首先是换档操作然后是最后两行的AND操作? – Because char-type can be unsigned and if we do the right shift for the negative value, eg 11111000 (-8), the most-significant bit will be copied; - 因为char-type可以是无符号的,如果我们对负值进行右移,例如11111000 (-8),则最高有效位将被复制; 11111000 >> 2 will result (1 filled from this end -->) 11111110 (-2). 11111000 >> 2将导致(1 filled from this end -->) 11111110 (-2)。 (See Right shifting negative numbers in C .) (参见右移C中的负数 。)

But back into function: 但回到功能:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM