如何重新排列位?

时间:2017-09-20 18:30:03

标签: c bit-shift

我必须在一个字节中重新创建位。我解决了这个问题:

uint8_t c;
uint8_t string[3];

string1[2] = (((c&(1<<0))!=0)<<6)|
             (((c&(1<<1))!=0)<<1)|
             (((c&(1<<2))!=0)<<0)|
             (((c&(1<<3))!=0)<<2)|
             (((c&(1<<4))!=0)<<3)|
             (((c&(1<<5))!=0)<<4)|
             (((c&(1<<6))!=0)<<5)|
             (((c&(1<<7))!=0)<<7);

basicly:

如果bit0为1,则向左移动1 6次。

如果bit1为1,则向左移动1 0次。 ....

有更好的解决方案吗?

2 个答案:

答案 0 :(得分:5)

(((c&(1<<x))!=0)<<y)

也可以写成

((c&(1<<x)))<<(y-x))

立即取消,每位消除一次操作。 (请记住,y-x是不变的。)

但那不是它。如果你在整个过程中应用这个转换,你会注意到一些位移了相同的数量。

(( c & 0x01 ) << 6 ) |
(( c & 0x02 )      ) |
(( c & 0x04 ) >> 2 ) |
(( c & 0x08 ) >> 1 ) |
(( c & 0x10 ) >> 1 ) |
(( c & 0x20 ) >> 1 ) |
(( c & 0x40 ) >> 1 ) |
(( c & 0x80 )      )

我们可以将这些分组。

(( c & 0x01 ) << 6 ) |
(( c & 0x82 )      ) |
(( c & 0x78 ) >> 1 ) |
(( c & 0x04 ) >> 2 )

我们将30个操作减少到10个。

答案 1 :(得分:0)

“更好”,如:“美丽在旁观者的眼中。”?

只需?另一种方式:(使用“否”!?除了作业以外的其他操作?)

Kernighan和Ritchie在第6章最后两节中的1988年第2版“C编程语言”解释了这段代码的细微之处和特质:

uint8_t c;
uint8_t string[3];

union { uint8_t  bits;
  struct { uint8_t t7    :1;
           uint8_t t3456 :4;
           uint8_t t2    :1;
           uint8_t t1    :1;
           uint8_t t0    :1;
         } bi;
  struct { uint8_t b7    :1;
           uint8_t b6    :1;
           uint8_t b2345 :4;
           uint8_t b1    :1;
           uint8_t b0    :1;
         } ti;
      } b,d;

  b.bits = d.bits = c;      // does b.ti.b1 = d.bi.t1; b.ti.b7 = d.bi.t7;

  b.ti.b0    = d.bi.t2;
  b.ti.b2345 = d.bi.t3456;
  b.ti.b6    = d.bi.t0;

  string[2] = b.bits;

有问题吗?阅读本书并考虑:

  struct { uint8_t t0    :1;
           uint8_t t1    :1;
           uint8_t t2    :1;
           uint8_t t3456 :4;
           uint8_t t7    :1;
          } bi;
  struct { uint8_t b0    :1;
           uint8_t b1    :1;
           uint8_t b2345 :4;
           uint8_t b6    :1;
           uint8_t b7    :1;
          } ti;