Complex Number Class
Home
Programs Home
This is a simplistic implementation of a Complex Number Class. It does
not contain a sample program to demonstrate its usage. However, you can
declare complex like any other built-in type object, and use it normally
like andy other built-in type. This class had the +, -, *, and /
operators overloaded, including the +=, -=, *=, and /= operators to
modify the object itself. The relational operators have been disabled in
this particular implementation, because I do not know how to compare 2
complex numbers, and even when I do, there is no way to define == in
terms of only the < operator. If any one knows how to do this, please
mail me at: printf ("%s@%s.com", "dhruvbird", "yahoo");
You can copy the code between the 2 HORIZONTAL LINES, paste it and save
it as ASCII test, and compile it with a standards compliant C++ compiler
such as g++.
/*a simplistic complex number class called m_complex.
please define the '*', and '/' operators appropriately.
the class 't' must have the +, -, <, ==, and = operators defined.
AUTHOR: Dhruv. Matani.
Date: Sunday, March 30, 2003.
This code is licensed under the GNU/GPL.
*/
#include<iostream>
using namespace std;
//absolute value.
template <class y> y absolute (const y&);
// class of complex data type
template <class t>
class m_complex {
private:
t re, imag;
public:
//constructors, and destructors.
m_complex (t real, t imaginary): re(real), imag(imaginary) { }
m_complex (t real): re(real), imag(static_cast<t>(0)) { }
m_complex ( ): re(static_cast<t>(0)), imag(static_cast<t>(0)) { }
virtual ~m_complex ( ) { }
//return the real and imaginary parts of the complex number.
t real (void) { return (re); }
t imaginary (void) { return (imag); }
//copy constructor, and copy asignment.
m_complex (const m_complex& comp_arg): re(comp_arg.re), imag(comp_arg.imag) { }
m_complex& operator= (const m_complex& comp_arg)
{
re = comp_arg.re;
imag = comp_arg.imag;
return (*this);
}
m_complex& operator= (const t& type_arg) { re = type_arg; imag = 0; return (*this); }
//end of copy, and assignment.
//template conversion form m_complex<some-data-type> to m_complex<another-data-type>.
template <class u>
operator m_complex<u> ( ) { return (m_complex<u>(static_cast<u>(re), static_cast<u>(imag))); }
//comparison operators. all defined in terms of < operator, and == operator.
//but, == is also defined in terms of <.
//I'm not even sure of whether it's logically correct for the complex numbers.
//bool operator< (const m_complex& comp_arg) { return (re < comp_arg.re && imag < comp_arg.imag); }
//bool operator== (const m_complex& comp_arg) { return (!((*this) < comp_arg || comp_arg < (*this))); }
//bool operator>= (const m_complex& comp_arg) { return (!((*this) < comp_arg)); }
//bool operator> (const m_complex& comp_arg) { return (!((*this) < comp_arg || (*this) == comp_arg)); }
//bool operator<= (const m_complex& comp_arg) { return (!((*this) > comp_arg)); }
//end of comparison operators.
//operator t( ) const { return (re); }
//misc.functons.
template <class c> friend m_complex<c> conjugate (const m_complex<c>&);
//end misc. functions.
//mathematical operations +=, and -=, and *=, and /=.
m_complex& operator+= (const m_complex& comp_arg)
{
re += comp_arg.re;
imag += comp_arg.imag;
return (*this);
}
m_complex& operator-= (const m_complex& comp_arg)
{
re -= comp_arg.re;
imag -= comp_arg.imag;
return (*this);
}
//there was a bug in operator*=, which gave wrong results, but
//has now been fixed. This also affected the opeartor/='s value
//indirectly, and also operatror* and operator/
m_complex& operator*= (const m_complex& comp_arg)
{
t temp;
temp = (re * comp_arg.re) - (imag * comp_arg.imag);
imag = (re * comp_arg.imag) + (comp_arg.re * imag);
re = temp;
return (*this);
}
m_complex& operator/= (const m_complex& comp_arg)
{
(*this) *= conjugate(comp_arg);
t temp = comp_arg.re * comp_arg.re + absolute(comp_arg.imag * comp_arg.imag);
re /= temp;
imag /= temp;
return (*this);
}
//end of mathematical operations.
//other math-ops.
template <class c> friend m_complex<c> operator+ (const m_complex<c>&, const m_complex<c>&);
template <class c> friend m_complex<c> operator- (const m_complex<c>&, const m_complex<c>&);
template <class c> friend m_complex<c> operator* (const m_complex<c>&, const m_complex<c>&);
template <class c> friend m_complex<c> operator/ (const m_complex<c>&, const m_complex<c>&);
//define operator*, and operator/.
//end other math-ops.
//display the complex number onto the screen <standard output>.
template <class c> friend ostream& operator<< (ostream&, const m_complex<c>&);
};
//misc. functions.
template <class c>
m_complex<c> conjugate (const m_complex<c>& comp_arg)
{
return (m_complex<c> (comp_arg.re, -comp_arg.imag));
}
template <class c>
m_complex<c> operator+ (const m_complex<c>& arg1, const m_complex<c>& arg2)
{
m_complex<c> retval (arg1);
retval += arg2;
return (retval);
}
template <class c>
m_complex<c> operator- (const m_complex<c>& arg1, const m_complex<c>& arg2)
{
m_complex<c> retval (arg1);
retval -= arg2;
return (retval);
}
template <class c>
m_complex<c> operator* (const m_complex<c>& arg1, const m_complex<c>& arg2)
{
m_complex<c> retval = arg1;
retval *= arg2;
return (retval);
}
template <class c>
m_complex<c> operator/ (const m_complex<c>& arg1, const m_complex<c>& arg2)
{
m_complex<c> retval = arg1;
retval /= arg2;
return (retval);
}
//ostream output.
template <class c>
ostream& operator<< (ostream& out, const m_complex<c>& comp_arg)
{
out<<comp_arg.re<<(comp_arg.imag >= 0 ? " + " : " - ")<<"i"<<absolute (comp_arg.imag);
return (out);
}
//generalized function, which returns the absolute value of
//any data type, which you can negate, or rather
//find the absolute value of.
template <class y>
y absolute (const y& type_y)
{
return (type_y < 0 ? -type_y : type_y);
}