Question

I need to convert from fixed point signed Q8 format to fixed point signed Q4 format in c. I assume that I can just do a bitshift by four, is this correct? Do I need to take into account the sign bit?

Update: This is for an ARM11 architecture, but I would prefer a non-architecture specific solution.

Thanks

Was it helpful?

Solution

A bitshift should work and will also take care of the sign bit on many architectures. In case of negative numbers, more ones will be shifted in but you will either only use the lower 5 Bits or do arithmetic in C where you need these additional ones to form the correct twos complement.

Assuming ints, the code would simply be:

int q4 = q8 >> 4;

Perhaps you would like to round:

int ahalf = q8 >= 0 ? (1<<3) : (1<<3)-1;
int q4 = (q8+ahalf) >> 4;

Ok, I listen to Oli and present a solution for architectures that do not shift sign-correct:

int q4 = q8 / (1<<4);

The optimizer should convert the division to a shift if possible.

With rounding, a first solution is

int ahalf = q8 >= 0 ? (1<<3) : -(1<<3);
int q4 = (q8+ahalf) / (1<<4);

Thanks to R..'s persistence I finally tested all versions and they now produce the correct results with Intel 32 Bit signed integers under Linux.

OTHER TIPS

I know C`s right shift behaviour is implementation defined. See 6.5.7/5 of the Standard

(some computers might copy the MSB as in the image below; others might add a '0')

It doesn't look like a lot of work to care about the sign bit.

But if your code is going to be compiled only on the same machine, you can check that machine implementation and ignore the sign bit if it "works"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top