From: Tim Wescott on
On 06/08/2010 09:55 AM, Frank wrote:
>> Is this C? Do you have to stick to C?
>
> It is C and I have to stick to C.
>
>
>> C really doesn't like Q1.anything -- it's only native fixed-point data
>> type is integer, and it sticks to it like glue. You can do fractional
>> fixed-point arithmetic _much_ faster in assembly -- if I'm working
>> with a processor that doesn't have really fast floating point math
>> then I'll write one -- it usually takes less than a day.
>
> I was trying to do it with some defines like these:
>
> #define TOQ15(x32) (((int16_t)(x32>>15)) & (int16_t)(((x32>>31)<<15) |
> 65535))
>
> The idea here is to shift a 32 bit value 15 bits down set bit 15 (the
> sign bit) correctly.
>
> #define MULXY(x16,y16) TOQ15(((int32_t)x16)*((int32_t)y16))
> #define ADDXY(x16,y16) TOQ15(((int32_t)x16)+((int32_t)y16))
>
> Some basic operations. However, there seems to be an error in the above
> defines...Have to debug it...
>
>
>> See chapter 10 of my book --
>> http://www.wescottdesign.com/actfes/actfes.html -- it presents a Q1.31
>> library for the x86; if you can understand assembly language
>> programming at all it should make clear what you need to do for
>> Q1.whatever math on your processor.
>
> Thank you. I will have a look at it (even though I still have to do the
> operations
> in C)....

You can do it all in ANSI-C as well (and I show it in the book, although
in the context of implementing Q1.31 using long long for arithmetic). I
just make functions and a test framework rather than using defines --
even with function call overhead you'll still be way faster than
floating point if the processor doesn't support it.

You're on the right track.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
From: Frank on

> You're on the right track.
>

Worked on it and came up with these macros:

#define TOQ15(x32) (((x32>>31)<<15)|(x32&0x7fff))
#define MULXY(x32,y32) TOQ15(((x32*y32)>>15))

So when I execute this code:

int16_t x1=-24576; // representing -0.75 in Q1.15
int16_t x2=4915; // representing 0.15 in Q1.15
int32_t acc=0; // expected 16bit signed integer value -3687

acc=MULXY(x1,x2);

I get -3687 in acc.....

Any comments ? Have I overlooked something?

From: Tim Wescott on
On 06/08/2010 12:07 PM, Frank wrote:
>
>> You're on the right track.
>>
>
> Worked on it and came up with these macros:
>
> #define TOQ15(x32) (((x32>>31)<<15)|(x32&0x7fff))
> #define MULXY(x32,y32) TOQ15(((x32*y32)>>15))
>
> So when I execute this code:
>
> int16_t x1=-24576; // representing -0.75 in Q1.15
> int16_t x2=4915; // representing 0.15 in Q1.15
> int32_t acc=0; // expected 16bit signed integer value -3687
>
> acc=MULXY(x1,x2);
>
> I get -3687 in acc.....
>
> Any comments ? Have I overlooked something?

Test the hell out of it. In particular test it for x1 = x2 = 0x8000 --
that's an amazing number in two's complement, and it can cause much grief.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
From: Randy Yates on
"Frank" <Frank(a)invalidmail.com> writes:

>> You're on the right track.
>>
>
> Worked on it and came up with these macros:
>
> #define TOQ15(x32) (((x32>>31)<<15)|(x32&0x7fff))
> #define MULXY(x32,y32) TOQ15(((x32*y32)>>15))
>
> So when I execute this code:
>
> int16_t x1=-24576; // representing -0.75 in Q1.15
> int16_t x2=4915; // representing 0.15 in Q1.15
> int32_t acc=0; // expected 16bit signed integer value -3687
>
> acc=MULXY(x1,x2);
>
> I get -3687 in acc.....
>
> Any comments ? Have I overlooked something?

Hi Frank,

You're making a mess!

First note that the compiler promotes the 16x16 bit multiply to a 32-bit
result in MULXY. Then note that shifting a 32-bit value right 31 bits
makes the LSB of the result either 0 or 1. Since these are signed
values, the compiler sign-extends the shift. Shifting 0 or 1 back left
15 bits gives you 0 or -32768, respectively. OR'ing that with the
x32&0x7FFF buys you nothing.

So all the work is really done in the argument to TOQ15, x32*y32 >> 15,
which is the right way to multiply two Q1.15 numbers and get a Q17.15
result.
--
Randy Yates % "So now it's getting late,
Digital Signal Labs % and those who hesitate
mailto://yates(a)ieee.org % got no one..."
http://www.digitalsignallabs.com % 'Waterfall', *Face The Music*, ELO
From: Randy Yates on
Tim Wescott <tim(a)seemywebsite.now> writes:
> [...]
> Is this C? Do you have to stick to C? C really doesn't like
> Q1.anything -- it's only native fixed-point data type is integer, and
> it sticks to it like glue.

Er, all fixed-point processing uses plain integer
operations. Fixed-point is all in how you interpret things.

There is nothing inherently "non-fixed-point" in C. C is just fine for
fixed-point processing.
--
Randy Yates % "Maybe one day I'll feel her cold embrace,
Digital Signal Labs % and kiss her interface,
mailto://yates(a)ieee.org % til then, I'll leave her alone."
http://www.digitalsignallabs.com % 'Yours Truly, 2095', *Time*, ELO