如何重新排列位?

问题描述 投票:0回答:3

我必须重新分配字节中的位。我是这样解决这个问题的:

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);

基本上:

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

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

有更好的解决办法吗?

c bit-shift
3个回答
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 个。


0
投票

“更好”如:“情人眼里出西施。”?

简单吗?另一种方式:(使用“no”!?除了赋值之外的操作?)

Kernighan 和 Ritchie 所著的 1988 年第二版《C 编程语言》第 6 章的最后两节解释了这段代码的微妙之处和特性:

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;

0
投票

如果你的内存很大,你可以使用你的函数在编译时生成一个长度=256的查找数组。当您在运行时执行重新排列作业时,只需在数组中查找即可。在最好的情况下,这可以将你的速度提高到 1 个时钟周期。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.