有效地将16位短路转换为8位短路

时间:2013-02-03 16:46:36

标签: c gcc embedded c99 integer-division

我正在研究一个没有硬件分区的Cortex M0 cpu,因此每次分割内容时都会使用GCC库函数。现在,我做的最多的除法之一就是除以256,将短路转换为字节。有没有什么方法可以比默认的GCC库更有效地(比如通过位移)做到这一点?

3 个答案:

答案 0 :(得分:7)

根据你的评论,你希望-32768映射到0,32767映射到255.因此,你想要的公式是:

short s = /* input value */;
unsigned char c = (unsigned char) ((s + 32768) / 256);

其他评论者已经注意到你可以通过右移或其他各种策略来划分256分,这是真的 - 合理的版本是:

unsigned char c = (unsigned char) ((s + 32768) >> 8);

但是,不需要这样的优化。 GCC非常聪明地将逐行操作转换为特殊情况实现,在这种情况下,它将这两者编译成完全相同的代码(使用-O2 -mcpu=cortex-m0 -mthumb和GCC 4.7.2测试):

    mov     r3, #128
    lsl     r3, r3, #8
    add     r0, r0, r3
    lsr     r0, r0, #8
    uxtb    r0, r0

如果你试图过于聪明(就像在其他答案中使用union或指针演示的例子一样),你可能会混淆它并让事情变得更糟 - 特别是因为那些工作是由内存加载,并且添加32768意味着你已经在寄存器中有了这个值。

答案 1 :(得分:2)

只是施放指针。

unsigned char *bytes = (unsigned char*)&yourvalue;

现在,bytes[0]将保留您的值的一个字节,bytes[1]将保留另一个字节。 订单取决于系统的字节顺序

答案 2 :(得分:1)

您可以这样使用union

#include <stdio.h>

union Word {
    struct {
        unsigned char high;
        unsigned char low;
    } byte;
    unsigned short word;
};

int main(int argc, char **argv) {

    union Word word;
    word.word = 0x1122;

    printf("L = 0x%x, H = 0x%x", word.byte.low, word.byte.high);

    return 0;
}