(我已经看到了这些问题(Convert Bytes to Int / uint in C和Converting 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]);
}
答案 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之前放置寄存器标签;