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?
source to share
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.
source to share
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;
}