Click here to Skip to main content
15,921,941 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,

I'm working on writing a C program to perform division of 2 complex numbers in Fixed Point.
I'm not able to get the fractional part from it. Below is more details on it.

I have 2 complex numbers:

N = a + ib
M = c + jd

I need to do N/M in fixed point (not using floating point)

Example values for the above complex numbers can be:

a = 1.55, b = 1.44, c = 1.24, d = 0.55

N = 1.55 + i(1.44)
M = 1.24 + j(0.55)

For converting to Fixed Point, I multiply these a, b, c and d with 2^14.
After that they become:
a = 0x6333, b = 0x5c28, c = 0x4f5c and d = 0x2333

Then to perform N/M operation I do:
N/M = (a + ib)/(c + jd) = ((a + ib) * (c - jd)) / ((c + jd) * (c - jd))

Then for real part alone:
(ac + bd) / (c^2 + d^2)

and so on..

The issue I'm facing is that I'm not understanding how to get the fractional part from the division.
I'm getting only the decimal part which is mostly either 1 or 0.

What is the correct way to get the fractional part? In the above example, the real part should be something like 1.47490. But I'm able to get only 1.

Can anyone please help me with the right way in doing the complex division for Fixed Point?

Thank you very much,
~Jinoj
Posted
Comments
Sinisa Hajnal 14-Nov-14 3:22am    
Assume your teacher is also reading these boards :)

1 solution

Your problem seems to be that you don't have the integer-based multiplication and division implemented correctly. Let's start with multiplication:

You said, you scale both operands by multiplying with 2^14. Then you have to scale the result by dividing through 2^28. For example:

C++
double a = 1.5;
double b = 3.6;

int as = (int) (a *(2<<14));
int bs = (int) (b *(2<<14));
int rss = as * bs;

double r = rss / (2<<28);

If you want to remain in your integer based 2^14 system you can do so by scaling the result back by dividing by 2^14.
C++
int as = (int) (a *(2<<14));
int bs = (int) (b *(2<<14));
int rs = (as * bs) >> 14;

This way the result will be scaled also by 2^14. You can easily convert it to a double by
C++
double r = ((double)rs) / (2<<14);

Now to division: If you want to divide two quantities that have been both scaled by 2^14, you should first scale the dividend by an additional factor of 2^14, otherwise the result will be unscaled and in your example mostly 0 or 1. Here is how to do it:
C++
int as = (int) (a *(2<<14));
int bs = (int) (b *(2<<14));
int rs = (a << 14) / b;

Again your result will be scaled by 2^14 and can be converted back to double as shown above.

Note that in the case of 32-bit integers, you will be limited to in the number space to an integer part of smaller than 8. This is, because your initial result will be scaled by 2^28, leaving just 4 bits for the integer part, one of which is the sign bit. Hence you might consider using type long long for your integer operations.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900