Efficiently convert 16 bit short characters to 8 bit char

I am working on a Cortex M0 cpu which has no hardware separation, so every time I divide something the GCC libary function is used. Now one of the divisions I do the most is divide by 256 to convert the shorts to bytes. Is there a way to do this more efficiently (using bit-shift for example) than the default GCC library would?

+3


source to share


3 answers


As per your comments, you want -32768 to map to 0 and 32767 to map to 255. So you want the formula:

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

      

Other commenters have pointed out that you can do this 256 split with the right or other tactic, which is correct - a reasonable version of this would be:

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

      



However, such optimizations are unnecessary. GCC is very good at converting constant division operations to implement special cases, in which case it compiles both of them into the same code (tested with -O2 -mcpu=cortex-m0 -mthumb

GCC 4.7.2 as well):

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

      

If you are trying to be too smart (as is the case with the union examples or with pointers to pointers in other answers), you are probably just confusing and getting something worse - especially since they work with memory, and adding 32768 means you already have a value in the register.

+7


source


just enter a pointer.

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

      



bytes[0]

will now hold one byte of your value and bytes[1]

will hold another. the order depends on the content of your system.

+2


source


You can use union

like this:

#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;
}

      

+1


source







All Articles