In: Computer Science
Lab Assignment Objectives
Understand the Application
Complex Numbers
A complex number, c, is an ordered pair of real numbers (doubles). For example, for any two real numbers, s and t, we can form the complex number:
This is only part of what makes a complex number complex. Another important aspect is the definition of special rules for adding, multiplying, dividing, etc. these ordered pairs. Complex numbers are more than simply x-y coordinates because of these operations. Examples of complex numbers in this format are (3, 3), (-1, -5), (1.034, 77.5) and (99.9, -108.5). You will build a class of complex numbers called Complex.
One important property of every complex number, c, is its length, or modulus, defined as follows. If c = (s, t) then:
For example:
The Program Specification
Create a class of Complex numbers.
Private Data
Public Instance Methods
Division By Zero
Create your own DivByZeroException as a nested class.
Make sure that both your reciprocal() and operator/() functions throw this exception (you can do this by only throwing it for reciprocal() if you do it correctly). Test it out in your client with a try/catch block, attempting both a normal, and a fatal division.
To test for division by zero, look at the reciprocal() and test for that being zero. However, not to test for == 0.0 exactly, because of inaccuracies in computer storage of doubles. Instead, pick a literal like .00000001 and proclaim the a complex object to be zero if its modulus (or modulus squared) is less than that literal value.
Description of the Operators
Operators +, -, * and /
Provide four overloaded operators, +, -, * and /. Implement these operators as friend methods of the class, so that Complex objects can be combined using these four operations. Also, allow a mixed mode operation containing a double and a Complex (which would return a Complex), by treating a double x, as if it were the complex number (x,0). This should come about naturally as a result of the Complex/Complex operators and the proper constructor definitions, not by creating 3 overloads for each operator.
The rules for adding complex numbers are:
(r,i) + (s,j) = (r + s, i + j).
Subtraction is defined analogously. Multiplication is defined by the rule:
(r,i) * (s,j) = (r*s - i*j, r*j + s*i).
To define division, first define the operation reciprocal of the complex number c = (r,i) as follows. c.reciprocal() should return the complex number = ( r / (r*r + i*i), -i / (r*r + i*i) ), if (r*r + i*i) is not zero. If (r*r + i*i) is zero, then reciprocal() throws an exception.
Then define division with the help of the reciprocal() function (informally):
(r,i) / (s,j) = (r,i) * reciprocal(s,j)
Notice that if you correspond a normal double number x, with its complex counterpart, (x,0), then you can think of the ordinary double numbers as a subset of the complex numbers. Also, note that, under this correspondence, these four operations result in ordinary addition, multiplication, etc. for the double subset. Try adding or dividing (6,0) and(3,0) for an example.
Testing Specification
In summary, you should be able to handle the combinations below:
Complex a(3,-4), b(1.1, 2.1), c; double x=2, y= -1.7; c = a + b; c = x - a; c = b * y; // and also: c = 8 + a; c = b / 3.2;
To help you confirm your computations, here are some examples:
(1, 2) + (3, 4) = (4, 6) (1, 2) - (3, 4) = (-2, -2) (1, 2) * (3, 4) = (-5, 10) (1, 2) / (3, 4) = (0.44, 0.08) (1, 2) + 10 = (11, 2) 10 / (3, 4) = (1.2, -1.6)
Operators << and =
Overload the insertion and assignment operators in the expected ways.
Operators < and ==
a < b should mean |a| < |b|, that is, a.modulus() < b.modulus(). a == b should mean (a.real == b.real) && (a.imag == b.imag). Define these two operators to make this so. (Note: < is not standard in math; there is no natural ordering mathematically for complex numbers. However, we will allow it to be defined this way in the problem.)
Pass all Complex parameters as const & and return all values of functions that sensibly return complex numbers (like operator+(), e.g.) as Complex values (not & parameters).
What to Turn In
To avoid Canvas adding a number to your complex files (i.e. same names as lab 5) prepend your initials.
For example: Ann Ohlone would be handing in the 3 files: aocomplex.h, aocomplex.cpp, a6.cpp
Hand in 3 files: No zip files.
operator (keyword) : Defines a new action
Syntax:
operator <operator symbol>( <parameters> )
{
<statements>;
}
The keyword "operator", followed by an operator symbol, defines
a new
(overloaded) action of the given operator.
Example:
complex operator +(complex c1, complex c2)
{
return complex(c1.real + c2.real, c1.imag + c2.imag);
}
Operator functions are same as normal functions. The only
differences are, name of an operator function is always operator
keyword followed by symbol of operator and operator functions are
called when the corresponding operator is used.
C++ program to overload different operators and apply on complex numbers(real and imaginary) :
#include<iostream.h>
#include<conio.h>
class complex
{
double real; // Real Part
double imag; // Imaginary part
public:
complex() { } // Constructor1
complex(double x,double y) // Constructor2
{
real=x; imag=y;
}
complex operator+(complex);
complex operator-(complex);
complex operator*(complex);
complex operator/(complex);
void toString(void);
};
complex complex::operator+(complex c)
{
complex temp;
// Temporary
temp.real=real+c.real;
// Float Addition
temp.imag=imag+c.imag;
// Float Addition
return(temp);
}
complex complex::operator-(complex c)
{
complex temp;
temp.real=real-c.real;
temp.imag=imag-c.imag;
return(temp);
}
complex complex::operator*(complex c)
{
complex temp;
temp.real=real*c.real-imag*c.imag;
temp.imag=real*c.imag+imag*c.real;
return(temp);
}
complex complex::operator/(complex c)
{
complex temp;
if(((c.real*c.real)+(c.imag*c.imag))!=0 &&
((c.real*c.real)+(c.imag*c.imag))!=0)
{
temp.real=((real*c.real)+(imag*c.imag))/((c.real*c.real)+(c.imag*c.imag));
temp.imag=((imag*c.real)-(real*c.imag))/((c.real*c.real)+(c.imag*c.imag));
}
else
cout<<"Cannot Divide By
Zero";
return(temp);
}
void complex::toString(void)
{
cout<<real<<" , "<<imag<<
"\n";
}
int main()
{
clrscr();
complex C1,C2,C3; // Invokes Constructor
1
C1=complex(2.5,3.4); // Invokes
Constructor 2
C2=complex(1.6,2.7); // Invokes
Constructor 3
C3=C1+C2;
cout<<"C1 = ";C1.toString();
cout<<"C2 = ";C2.toString();
cout<<"Complex Addition = ";C3.toString();
C1=complex(2.5,3.6);
C2=complex(1.6,2.9);
C3=C1-C2;
cout<<"C1 = ";C1.toString();
cout<<"C2 = ";C2.toString();
cout<<"Complex Substraction =
";C3.toString();
C1=complex(1,2);
C2=complex(3,4);
C3=C1*C2;
cout<<"C1 = ";C1.toString();
cout<<"C2 = ";C2.toString();
cout<<"Complex Multiplication =
";C3.toString();
C1=complex(1,2);
C2=complex(3,4);
C3=C1/C2;
cout<<"C1 = ";C1.toString();
cout<<"C2 = ";C2.toString();
cout<<"Complex Division = ";C3.toString();
getch();
return 0;
}
OUTPUT