Sign in

Not a member? | Forgot your Password?

Search compdsp

Search tips


Discussion Groups

IIR Filter Design Software

Free Online Books

See Also

Embedded SystemsFPGA

Discussion Groups | Comp.DSP | Q1.15 calculation

There are 30 messages in this thread.

You are currently looking at messages 1 to .


Is this discussion worth a thumbs up?

0

Q1.15 calculation - Frank - 2010-06-08 05:49:00

Hey guys,

I was wondering if you could help me optimize the code below (if possible):

R = (B*X);
tmp = (int16_t) (R>>15);
R = ((int32_t)tmp)+Z;
tmp = (int16_t)R;
R = (A*((int32_t)Y));
tmp2 = -(int16_t) (R>>15);
Rout=tmp+tmp2;

Rout is a SINT16 variable containing a Q1.15 value
A and B will be replaced by a number between -32768 and 32767
tmp and tmp2 are SINT16 variables; each containing a Q1.15 value
Z is a SINT32 variable containing a Q1.15 value
Y is a SINT16 variable containing a Q1.15 value
R is a SINT32 variable containing the result of an operation on two Q1.15 
values
X is a SINT32 variable containing a Q1.15 value

The above code looks too messy to me and I'm sure it can be optimized..Or 
maybe I am wrong?
Basically I just want to do some operations on Q1.15 numbers in a 32-bit 
cell.

Thank you in advance.

_____________________________
 Free pdf download: Digital Signal Processing Maths.


Re: Q1.15 calculation - robert bristow-johnson - 2010-06-08 11:59:00

On Jun 8, 5:49 am, "Frank" <Fr...@invalidmail.com> wrote:
>
> Basically I just want to do some operations on Q1.15 numbers in a 32-bit
> cell.

so left-justify it and call it a Q1.31 number (where the 16 LSBs are
zero).  or right justify it and call it a Q16.16 number.

the code looks like C where you've typedeffed some things.

r b-j

_____________________________
 Free pdf download: Digital Signal Processor Fundamentals and System Design.


Re: Q1.15 calculation - Tim Wescott - 2010-06-08 12:23:00

On 06/08/2010 02:49 AM, Frank wrote:
> Hey guys,
>
> I was wondering if you could help me optimize the code below (if
possible):
>
> R = (B*X);
> tmp = (int16_t) (R>>15);
> R = ((int32_t)tmp)+Z;
> tmp = (int16_t)R;
> R = (A*((int32_t)Y));
> tmp2 = -(int16_t) (R>>15);
> Rout=tmp+tmp2;
>
> Rout is a SINT16 variable containing a Q1.15 value
> A and B will be replaced by a number between -32768 and 32767
> tmp and tmp2 are SINT16 variables; each containing a Q1.15 value
> Z is a SINT32 variable containing a Q1.15 value
> Y is a SINT16 variable containing a Q1.15 value
> R is a SINT32 variable containing the result of an operation on two
> Q1.15 values
> X is a SINT32 variable containing a Q1.15 value
>
> The above code looks too messy to me and I'm sure it can be
> optimized..Or maybe I am wrong?
> Basically I just want to do some operations on Q1.15 numbers in a 32-bit
> cell.
>
> Thank you in advance.
>
>
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.  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.

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.

-- 
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com

_____________________________
 Free pdf download: Digital Signal Processor Fundamentals and System Design.


Re: Q1.15 calculation - Frank - 2010-06-08 12:55:00

> 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)....

_____________________________
 Free pdf download: Digital Signal Processing Maths.


Re: Q1.15 calculation - Frank - 2010-06-08 12:57:00

>so left-justify it and call it a Q1.31 number (where the 16 LSBs are
>zero).  or right justify it and call it a Q16.16 number.

Yeah...i guess...but how does that answer my question? :o)

_____________________________
 Free pdf download: Digital Signal Processor Fundamentals and System Design.


Re: Q1.15 calculation - Tim Wescott - 2010-06-08 14:18:00

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

_____________________________
 Free pdf download: Digital Signal Processing Maths.


Re: Q1.15 calculation - Frank - 2010-06-08 15:07:00

> 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 x2I15; // 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?

_____________________________
 Free pdf download: Digital Signal Processing Maths.


Re: Q1.15 calculation - Tim Wescott - 2010-06-08 18:24:00

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 x2I15; // 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

_____________________________
 Free pdf download: Digital Signal Processing Maths.


Re: Q1.15 calculation - Randy Yates - 2010-06-08 21:51:00

"Frank" <F...@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 x2I15; // 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://y...@ieee.org          %    got no one..."
http://www.digitalsignallabs.com % 'Waterfall', *Face The Music*, ELO

_____________________________
 Free pdf download: Digital Signal Processor Fundamentals and System Design.


Re: Q1.15 calculation - Randy Yates - 2010-06-08 21:58:00

Tim Wescott <t...@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://y...@ieee.org          %            til then, I'll leave her
alone."
http://www.digitalsignallabs.com %        'Yours Truly, 2095', *Time*, ELO

_____________________________
 Free pdf download: Digital Signal Processing Maths.


| 1 | | 3 |