//////////////////////////////////////////////////////////
//
// complex.cpp - Implementation of complex number class
//
//////////////////////////////////////////////////////////

#include <iostream.h>
#include <assert.h>
#include <math.h>				// sqrt()
#include "complex.h"

void Complex::add(const Complex& c)				//non-inlined member fns.
{
	real += c.real;
	imag += c.imag;
}

void Complex::sub(const Complex& c)
{
	real -= c.real;
	imag -= c.imag;
}

const double Complex::abs() const
{
	return sqrt(real * real + imag * imag);
}

// Global operators overloaded for class Complex:

istream& operator>>(istream& is, Complex& c)
{
	return is >> c.real >> c.imag;
}

ostream& operator<<(ostream& os, const Complex& c)
{
	os << "(" << c.real << (c.imag < 0 ? "" : "+") << c.imag << "i" << ")";
	return os;
}

// Global arithmetic operators overloaded on class Complex

const Complex operator+(const Complex& left, const Complex& right)
{
	return Complex(left.real + right.real, left.imag + right.imag);
}

const Complex operator-(const Complex& left, const Complex& right)
{
	return Complex(left.real - right.real, left.imag - right.imag);
}

const Complex operator*(const Complex& left, const Complex& right)
{
	return Complex(left.real * right.real - left.imag * right.imag,
						left.real * right.imag + left.imag * right.real);
}

const Complex operator/(const Complex& left, const Complex& right)
{
	float num1, num2, denom;

	num1 = left.real * right.real + left.imag * right.imag;
	num2 = left.imag * right.real - left.real * right.imag;
	denom = right.real * right.real + right.imag * right.imag;
	assert(denom);

	return Complex(num1/denom, num2/denom);
}

// Global logical operators overloaded on class Complex

const bool operator==(const Complex& left, const Complex& right)
{
	return (left.real == right.real) && (left.imag == right.imag);
}

const bool operator!=(const Complex& left, const Complex& right)
{
	return (left.real != right.real) || (left.imag != right.imag);
}

const bool operator<=(const Complex& left, const Complex& right)
{
	return left.abs() <= right.abs();
}

const bool operator>=(const Complex& left, const Complex& right)
{
	return left.abs() >= right.abs();
}

const bool operator<(const Complex& left, const Complex& right)
{
	return left.abs() < right.abs();
}

const bool operator>(const Complex& left, const Complex& right)
{
	return left.abs() > right.abs();
}

// Global mathematical assignment operators overloaded on class Complex

const Complex& operator+=(Complex& left, const Complex& right)
{
	left.real += right.real;
	left.imag += right.imag;
	// also could just do: left = left + right;
	return left;
}

const Complex& operator-=(Complex& left, const Complex& right)
{
	left.real -= right.real;
	left.imag -= right.imag;
	// also could just do: left = left - right;
	return left;
}

const Complex& operator*=(Complex& left, const Complex& right)
{
	left = left * right;
	return left;
}

const Complex& operator/=(Complex& left, const Complex& right)
{
	left = left / right;
	return left;
}