# fixed point arithmetic in c

1. ## fixed point arithmetic in c

I am looking for a C code to perform Q15 addition, subtraction, multiplication, division , sine(x) and cosine(x). Can anybody provide good reference that works?

2. ## Re: fixed point arithmetic in c

I'd start with searching "fixed point [add/subtract/mult]" etc. There are different options for each. Saying its fixed point also doesn't tell us if you have hardware multiply/divide support though I'll assume no.

Understand that a lot of it comes down to designing your algorithms around the limitations. For example if you don't have hardware multiply then plan around doing power of 2 shift divides with << and >>. Sin and cos are typically implemented with a look-up-table.

•

3. ## Re: fixed point arithmetic in c

short a, b, c;
Addition: c = a + b;
Subtraction: c = a - b;
Multiplication: c = (short)((a * (long)b) >> 15);

4. ## Re: fixed point arithmetic in c

how to take care of oveflow for addition and subtraction? c should be short or long?

5. ## Re: fixed point arithmetic in c

Originally Posted by curious_mind
how to take care of oveflow for addition and subtraction? c should be short or long?
You'd need to use long - or an MCU that supports saturating fixed-point types.

6. ## Re: fixed point arithmetic in c

Hi

I am considering 2's complement unsigned data that varies from 0 to 65535. What would happen if I would add 10 with 32767. The result is a negative number. How would I guard this?

7. ## Re: fixed point arithmetic in c

Your specification is rather shallow. You say "take care of overflow". How? Saturate? Generate an exception?

In case, additional code is required. The CPU may be already able to detect a signed integer overflow. Or you detect it by monitoring the arguments and result signs.

8. ## Re: fixed point arithmetic in c

I came up with the following custom c code. Your view on this will be helpful
Code:
```unsigned int add (unsigned int a ,unsigned  int b)
{
unsigned int res;
unsigned long tmp;
tmp=a+b;
if((a<=32767) && (b<=32767))   // both numbers are positive
{
if (tmp>32767)
{
res=32767;
}
}

else if((a>32767) && (b>32767))  // both numbers are negative
{
if (tmp>32768)
{
res=32768;
}
}
else
{
res=tmp & 0xffff;
}
return(res);
}

unsigned int sub (unsigned int a ,unsigned  int b)
{
unsigned int res;
unsigned long tmp;

if((a<=32767) && ( b>=32768) || (a>=32768) && (b<=32767))
{
if(a>b)
{
res=32768;
}
else
{
res=32767;
}
}
else
{
tmp=a-b;
res=tmp & 0xffff;
}

return(res);
}```

•

9. ## Re: fixed point arithmetic in c

Looks O.K. as a demonstration but can be coded more efficiently using bit operations.

10. ## Re: fixed point arithmetic in c

Stuck with basics operations again in Q1.15 multiplication. What should be the result of multiplication of 23166 (0.707) and 65535 (0.0), the result is 46332 and not 65535. Could it be clarified? It is very basic question

11. ## Re: fixed point arithmetic in c

Apparently you don't scale the multiply result correctly.

12. ## Re: fixed point arithmetic in c

I used the following code

a=23166, b=65535;

long result,a,b;

result =(a*b)>>15;

13. ## Re: fixed point arithmetic in c

b=65535 is outside Q1.15 (int16) range. Should be -1.

14. ## Re: fixed point arithmetic in c

Q1.15 range is -1.0 to +1.0 , -32768 to 32767, in hex it is 0x8000-0xffff for negative range and 0x0000-0x7fff for positive range, so 65535 is around -1. So I guess it is the valid range.

•

15. ## Re: fixed point arithmetic in c

The two's complement format is good for addition/subtraction, but bad for multiplication/division.
You want to multiply Q1.15 values 23166 (0.707) with 65535 (-0.0003)
The simplest solution is to separate the sign calculation from the magnitude calculation.
You multiply a positive value with a negative value, so the result will be negative.
For the magnitude calculation, convert the negative value 65535 to the corresponding positive value 1.
Multiply 23166 with 1 => 23166.
Shift down 15 bits => 0
With rounding before shift, the result will be 1.
We then remember that the result should be negative, so we convert 1 to 65535.

16. ## Re: fixed point arithmetic in c

so 65535 is around -1
Not when represented with long data type as in post #12.

17. ## Re: fixed point arithmetic in c

fixed point multiplication issue is resolved. Thanks for all help

--[[ ]]--