将字节数组转换为整数而不循环的方法?

时间:2014-03-02 15:01:35

标签: c arduino

(我已经看到了这些问题(Convert Bytes to Int / uint in CConverting Byte Array To Int24),但它们似乎比我想做的更复杂,所以我想我会问。)

我正在Arduino / Wiring中进行一些LED矩阵编程。由于这里可能不相关的原因,我有一个字节数组表示LED行的“位状态”,我用它来缓冲其他操作的结果。要实际设置LED(我使用的是Maxim 7219芯片),我需要从字节数组中导出一个整数。

使用Arduino / Wiring bitWrite方法,我的下面的一个简单的例子程序可以工作,但我想知道是否有一个比循环更快的C方法。

 byte dog[8] = {0,0,1,1,1,1,1,0};
 byte cat;

 for (int i = 0; i < 8; i++){
  bitWrite(cat, i, dog[7-i]);
 }

2 个答案:

答案 0 :(得分:4)

您可以展开循环:

bitWrite(cat, 0, dog[7]);
bitWrite(cat, 1, dog[6]);
bitWrite(cat, 2, dog[5]);
bitWrite(cat, 3, dog[4]);
bitWrite(cat, 4, dog[3]);
bitWrite(cat, 5, dog[2]);
bitWrite(cat, 6, dog[1]);
bitWrite(cat, 7, dog[0]);

或者设置没有库函数的位(仅当字节保证为0或1时才有效):

cat = (dog[7] << 0) |
      (dog[6] << 1) |
      (dog[5] << 2) |
      (dog[4] << 3) |
      (dog[3] << 4) |
      (dog[2] << 5) |
      (dog[1] << 6) |
      (dog[0] << 7);

但是C中没有任何东西用一个命令来构建它,所以它可能不会比这快得多。

编辑:通过一些有点蠢蠢欲动的技巧,这可能(可能)加速了一点。类似下面的内容应该适用于小端32位处理器:

uint32_t int_dog = (uint32_t*)dog;
uint32_t t0, t1;

t0 = int_dog[0];   // .......3.......2.......1.......0
t0 |= t0 << 9;     // ......23......12......01.......0
t0 |= t0 << 18;    // ....0123.....012......01.......0
t1 = int_dog[1];   // .......7.......6.......5.......4
t1 |= t1 << 9;     // ......67......56......45.......4
t1 |= t1 << 18;    // ....4567.....456......45.......4
cat = (t0 >> 20) | (t1 >> 24);

答案 1 :(得分:-2)

这很垃圾,但你可以用goto标签来做到这一点:

byte dog[8] = {0,0,1,1,1,1,1,0};
byte cat;
int i = 0;

BitWriteBeginning:    
bitWrite(cat, i, dog[7-i]);
i++
if (i < 8)
   goto BitWriteBeginning;

但即使如此,我也不确定它会更有效率。它仍然是评估的条件,编译器可能无法对其进行优化(例如将i放入ecx中)。

所以你可以做更丑((D),在int i = 0之前放置寄存器标签;