Nusrat Nuriyev
asked on
Understanding complex numbers recursive power in C++
I have written the complex number class, with method of finding power of the complex number using recusrion.
But I have not understand till the end how it work (that sounds weird)
So your aim is to explain why it works.
My idea is that the variable
comp t has different address at each recusive call so it may accumulate all chain of recusrive call correctly.
when I write this
instead of this
it writes to the same address, the address of this?
Who may explain in detail?
But I have not understand till the end how it work (that sounds weird)
So your aim is to explain why it works.
My idea is that the variable
comp t has different address at each recusive call so it may accumulate all chain of recusrive call correctly.
when I write this
return *this * rec_power(base, n-1);
instead of this
comp t = *this * rec_power(base, n-1);
return t;
it writes to the same address, the address of this?
Who may explain in detail?
#include <iostream>
#include <fstream>
#include <cmath>
#include <iomanip>
using namespace std;
template <typename T>
class comp
{
public:
T im;
T re;
public:
// Constructor with parameters
comp(T re, T im)
{
this->im = im;
this->re = re;
}
// Default constructor
comp()
{
this->im = 0;
this->re = 0;
}
// Constructor with one param. Assuming that single parameter
// is the real part of the comple number
comp(T re)
{
this->re = re;
}
// Copy constructor
comp(const comp& c)
{
re = c.re;
im = c.im;
}
// Empty destructor
~comp() {};
comp& operator+(comp& second)
{
comp result;
result.re = this->re + second.re;
result.im = this->im + second.im;
return result;
}
// Multiplying a complex number by another complex number
comp& operator*(comp& second)
{
comp result;
result.re = this->re * second.re + (-1)* this->im * second.im;
result.im = this->re * second.im + this->im * second.re;
return result;
}
// Multiplying a complex number by another number number
comp& operator*(T n)
{
comp result;
result.re = this->re * n;
result.im = this->im * n;
return result;
}
T modulus()
{
return sqrt(this->re*this->re + this->im*this->im);
}
comp& it_power(int n)
{
comp result(1, 0);
for (int i = 1; i <= n; i++)
result = *this * result;
return result;
}
comp& rec_power(comp base, int n)
{
comp one(1, 0);
if (n == 0)
return one;
else if (n == 1)
return *this;
else
{
comp t = *this * rec_power(base, n-1);
return t;
// investigate why this does not work
//return *this * rec_power(base, n-1);
}
}
// Overloading input operator
friend std::ostream& operator<<(ostream& out, comp& c)
{
out << setprecision(2) << fixed
<< "(" << c.re << ", " << c.im
<< "i)" << endl;
return out;
}
// Overloading output operator
friend std::istream& operator>>(istream& in, comp& c)
{
in >> c.re ;
in >> c.im;
return in;
}
};
int main()
{
comp<double> myc(3, 2);
comp<double> myc2(1, 4);
// cin >> myc;
// cin >> myc2;
comp<double> r = myc + myc2;
comp<double> m = myc * myc;
cout << r;
cout << m;
cout << r.modulus() << endl;
cout << m.modulus() << endl;
cout << myc.it_power(6) << endl;
cout << myc.rec_power(myc, 6) << endl;
return 0;
}
Incidentally, generally speaking it is best to avoid recursion where possible by using for loops or similar, like you do in your it_power() method.
ASKER
Could you provide any arguments?
ASKER
It was about understanding how recursion work with class methods, not about practical usage.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
// investigate why this does not worki would guess it will be accepted by the compiler if you changed the return type to value type.
//return *this * rec_power(base, n-1);
i also would recommend to using (*this) to make the statement better readable.
Sara
Sorry about the delay. Thankfully for you, Sara has participated in this question and has provided, as usual, valuable input :)
You should try to avoid recursion because (depending on how deep you recurse) it can lead to stack overflows (for every recursive call, amongst other actions, stack space is allocated and variable state is saved. If you recurse too many times, you can run out of stack ("stack overflow")).
As far as I know, recursion is the same for class methods as it is for none-class methods.
Additionally, when you change the return type of your functions to value, not reference, as both Sara and I suggested,
...is fundamentally no different to ...
...except that in the latter, you are creating a named temporary (you call this 't'). The former will still create a 'comp' object, and it will still be copied when it is returned.
You should try to avoid recursion because (depending on how deep you recurse) it can lead to stack overflows (for every recursive call, amongst other actions, stack space is allocated and variable state is saved. If you recurse too many times, you can run out of stack ("stack overflow")).
As far as I know, recursion is the same for class methods as it is for none-class methods.
Additionally, when you change the return type of your functions to value, not reference, as both Sara and I suggested,
return *this * rec_power(base, n-1);
...is fundamentally no different to ...
comp t = *this * rec_power(base, n-1);
return t;
...except that in the latter, you are creating a named temporary (you call this 't'). The former will still create a 'comp' object, and it will still be copied when it is returned.
ASKER
sarabande,
when I write this
it returns following:
when I write this
comp rec_power(comp base, int n)
{
if (n == 0)
return comp(1,0);
comp t = (*this) * rec_power(base, n-1);
return t;
// investigate why this does not work
//return *this * rec_power(base, n-1);
}
it returns following:
C:\Complex2\main.cpp|98|error: no match for 'operator*' in '*(comp<double>*)this * comp<T>::rec_power(comp<T> , int) [with T = double; comp<T> = comp<double>](comp<double> ((*(const comp<double>*)(& base))), (n + -1))'|
ASKER
// investigate why this does not work
//return *this * rec_power(base, n-1);
i would guess it will be accepted by the compiler if you changed the return type to value type.
Can't get this.
//return *this * rec_power(base, n-1);
i would guess it will be accepted by the compiler if you changed the return type to value type.
Can't get this.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Open in new window
This will update the object on which the function is being called (the "this" pointer).
Open in new window
This will return a new object, without modifying the object on which the function is being called.
Incidentally, your code has a lot of semantic errors in that you return references to temporary objects; for example,
Open in new window
You create the variable 'result' on the stack, and return a reference to it. When it_power() returns, that object will be destroyed hence you will return a reference to rubbish memory. I suggest you remove all occurrences of such code.