How can I fix my C++ code to calculate Complex numbers? - c++

I have got some problems with my main.cpp.There are some places where I do not know what I have to write to make my code work well. I will write in my code where the problems are. I write the Problem word where my code is wrong. Does anybody have an idea what I have to change to make my code work?
My code is about Complex numbers add,sub,divide,mul.
Komolex.h :
#pragma once
#include <iostream>
class NullDivision : public std::exception{};
class Complex{
private:
int n, d;
public:
Complex(int _n = 0, int _d = 1) : n(_n), d(_d)
{
if(d == 0)
{
throw NullDivision();
}
}
Complex add(const Complex &b) const
{
Complex c(n + b.n , d + b.d);
return c;
}
Complex sub(const Complex &b) const
{
Complex c(n - b.n , d - b.d);
return c;
}
Complex mul(const Complex &b) const
{
Complex c(n * b.n - d * b.d ,n * b.d - d * b.n );
return c;
}
Complex div(const Complex &b) const
{
if(b.n == 0 || b.d == 0)
{
throw NullDivision();
}
Complex c((n * d + d * b.d ) / (b.n * b.n + b.d * b.d ), (d * b.n + n * b.d )/(b.n * b.n + b.d * b.d));
return c;
}
friend Complex operator+(const Complex &a, const Complex &b)
{
return Complex(a.n + b.n , a.d + b.d);
}
friend Complex operator-(const Complex &a, const Complex &b)
{
return Complex(a.n - b.n , a.d - b.d);
}
friend Complex operator*(const Complex &a, const Complex &b)
{
return Complex(a.n * b.n - a.d * b.d ,a.n * b.d - a.d * b.n );
}
friend Complex operator/(const Complex &a, const Complex &b)
{
if(b.n == 0)
{
throw NullDivision();
}
return Complex((a.n * a.d + a.d * b.d ) / (b.n * b.n + b.d * b.d ), (a.d * b.n + a.n * b.d )/(b.n * b.n + b.d * b.d));
}
friend std::ostream& operator<< (std::ostream& o, const Complex &a)
{
o << "(" << a.n << "/" << a.d << ")";
return o;
}
};
main.cpp :
#include <iostream>
#include "Komplex.h"
using namespace std;
int main()
{ bool fut = false;
int szam;
while (fut == false){
cout << "1.Komplex számok összeadása" << endl;
cout << "2.Komplex számok kivonása" << endl;
cout << "3.Komplex számok szorzása"<< endl;
cout << "4.Komplex számok osztása"<< endl;
cout << "5.Kilépés"<< endl;
cout << "Írjon be egy sorszámot!"<< endl;
cin >> szam;
if(szam == 5)
{
fut=true;
break;
}
cout << endl;
Complex n, d;
cout << "Adja meg az első szám valós részét" << endl;
cin >> n.a; // Problem
cout << "Adja meg az első szám képzetes részét" << endl;
cin >> n.b; // Problem
cout << "Adja meg a második szám valós részét" << endl;
cin >> d.a; // Problem
cout << "Adja meg a második szám képzetes részét" << endl;
cin >> d.b; // Problem
Complex eredmeny;
switch(szam){
case 1:
eredmeny = n + d;
cout << "Az eredmény:" << eredmeny.a << + eredmeny.b << "i" << endl << endl;
break;
case 2:
eredmeny = n - d;
cout << "Az eredmény:" << eredmeny.a << + eredmeny.b << "i" << endl << endl;
break;
case 3:
eredmeny = n * d;
cout << "Az eredmény:" << eredmeny.a << + eredmeny.b << "i" << endl << endl;
break;
case 4:
try {
eredmeny = n / d;
cout << "Az eredmény:" << eredmeny.a << + eredmeny.b << "i" << endl << endl;
}
catch(NullDivision e){std::cout << "NullDivision"<< std::endl;}
std::cout << std::endl;
break;
}
}
return 0;
}

Your Complex class has two member variables, n and d. You appear to be trying to put values into the (non-existent) a and b member variables.
That's not going to end well :-)
I would suggest, for a start, using variable names that make your intent clearer. For example, member variables n and d would be far better named as something like m_real and m_imag (n and d look like they should represent numerator and denominator, but that has nothing to do with complex numbers(a)).
By using decent variable names, reading of the code should be enough to figure out what's happening and you're unlikely to get confused between member variables and objects of the class (which also shouldn't be named n and d).
(a) To be honest, it looks like you've re-tasked some code meant to do rationals to be used as complex numbers. I base this on the variable naming and the fact your Complex constructor has:
Complex(int _n = 0, int _d = 1) : n(_n), d(_d)
{
if(d == 0)
{
throw NullDivision();
}
}
I can see no reason why the imaginary part of a complex number would default to one, nor why you would throw a NullDivision exception if it was zero. That would basically remove the entire set of real numbers from your complex class.
So, it's even more important that you use better names so that you can figure out why these re-tasked things are wrong.
I'm going to give you an example of how a professional developer would code up something like this (albeit without the copious comments I normally have).
I wouldn't suggest using this if this is educational classwork since you're likely to get pinged for plagiarism but it should serve as a guide on how to do it.
#include <iostream>
class ZeroDivision : public std::exception{};
struct Complex{
public:
Complex(double real_bit = 0.0, double imag_bit = 0.0)
: m_real(real_bit)
, m_imag(imag_bit)
{}
friend Complex operator+(const Complex &me, const Complex &them) {
return Complex(
me.m_real + them.m_real,
me.m_imag + them.m_imag);
}
friend Complex operator-(const Complex &me, const Complex &them) {
return Complex(
me.m_real - them.m_real,
me.m_imag - them.m_imag);
}
friend Complex operator*(const Complex &me, const Complex &them) {
return Complex(
me.m_real * them.m_real - me.m_imag * them.m_imag,
me.m_real * them.m_imag + me.m_imag * them.m_real);
}
friend Complex operator/(const Complex &me, const Complex &them) {
if (them.m_real == 0 && them.m_imag == 0)
throw ZeroDivision();
return Complex(
(me.m_real * them.m_real + me.m_imag * them.m_imag) / (them.m_real * them.m_real + them.m_imag * them.m_imag),
(me.m_imag * them.m_real - me.m_real * them.m_imag) / (them.m_real * them.m_real + them.m_imag * them.m_imag));
}
friend std::ostream& operator<<(std::ostream& os, const Complex &var) {
const char *sep = "+";
if (var.m_imag < 0)
sep = "";
os << "(" << var.m_real << sep << var.m_imag << "i)";
return os;
}
private:
double m_real, m_imag;
};
#include <iostream>
using namespace std;
int main() {
Complex c1(19.65, 3.142);
Complex c2(19.68, 2.718);
Complex c3(2, 0);
Complex c4(0, 2);
Complex c5(0, 0);
cout << c1 << " + " << c2 << " = " << (c1 + c2) << '\n';
cout << c1 << " - " << c2 << " = " << (c1 - c2) << '\n';
cout << c1 << " * " << c2 << " = " << (c1 * c2) << '\n';
cout << c1 << " / " << c2 << " = " << (c1 / c2) << '\n';
cout << c1 << " / " << c3 << " = " << (c1 / c3) << '\n';
cout << c1 << " / " << c4 << " = " << (c1 / c4) << '\n';
try {
cout << c1 << " / " << c5 << " = " << (c1 / c5) << '\n';
cout << "Did NOT successfully catch divide-by-zero\n";
} catch (ZeroDivision &exc) {
cout << "Successfully caught divide-by-zero\n";
}
return 0;
}
As part of this, I:
Got rid of superfluous stuff. There's little point having add, sub, and so on, when you can just use the built-in operators.
Created all complex numbers using the constructors (or operators). You should not be trying to change a classes internal (private) data. If you must do that, use a setter function.
Made a (very slight) adjustment to your output stream code to improve the format. And again, this is what you should use to output an object, not attempting to directly access private data.
Fixed the divide-by-zero detection. This only happens if both the real and imaginary parts are zero whereas you raised it if either were. That would bean you could never divide something by two since the imaginary part is zero, (2+0i).
Made the parts floating point rather than integers. You can change them back if you wish but the floating point is probably better in a general purpose class.
Fixed your multiplication and division formulae.
To explain that final bullet point, what you had for multiplication a * b was, where a and b are the complex numbers, R is the real part, I the imaginary:
R = a.R * b.R - a.I * b.I # correct.
I = a.R * b.I - a.I * b.R # should be adding, not subtracting
^
For division a / b, you had:
R = (a.R * a.I + a.I * b.I) / (b.R * b.R + b.I * b.I)
(a.R * a.R + a.I * b.I) / (b.R * b.R + b.I * b.I) <- should be
^
I = (a.I * b.R + a.R * b.I) / (b.R * b.R + b.I * b.I)
(a.I * b.R - a.R * b.I) / (b.R * b.R + b.I * b.I) <- should be
^
The run of that test code generates these results (reformatted for readability):
(19.65+3.142i) + (19.68+2.718i) = (39.33+5.86i)
(19.65+3.142i) - (19.68+2.718i) = (-0.03+0.424i)
(19.65+3.142i) * (19.68+2.718i) = (378.172+115.243i)
(19.65+3.142i) / (19.68+2.718i) = (1.00142+0.021348i)
(19.65+3.142i) / (2+0i) = (9.825+1.571i)
(19.65+3.142i) / (0+2i) = (1.571-9.825i)
(19.65+3.142i) / (0+0i) = Successfully caught divide-by-zero

Related

Wrong root from quadratic equation calculator

I was wondering if someone could help me in this problem.
So i tested the code but it didn't show the right answer below for
equation result of x2 + 5x + 6
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
double roots() {
double a, b, c, x1, x2;
cout << "Enter quadratic equation in order (a, b, c): \n";
cin >> a >> b >> c;
double discriminant = b * b - 4 * a * c;
x1 = -b + sqrt(discriminant) / 2 * a;
x2 = -b - sqrt(discriminant) / 2 * a;
if (discriminant >= 0 && a > 1) {
cout << "Your quadratic equation is " << a << "x^2 + " << b << " x + " << c << '\n';
cout << "x1 = " << x1 << '\n';
cout << "x2 = " << x2 << '\n';
}
else if (a == 1) {
cout << "Your quadratic equation is " << "x^2 + " << b << " x + " << c << '\n';
cout << "x1 = " << x1 << '\n';
cout << "x2 = " << x2 << '\n';
}
else {
cout << "Negative value returned from (b2 - 4ac), please try again!";
exit(1);
}
}
int main() {
roots();
}
You have the formula incorrect. Try this
x1 = (-b + sqrt(discriminant)) / (2 * a);
x2 = (-b - sqrt(discriminant)) / (2 * a);
Notice the extra parenthesis in order to put 2*a in the denominator and have it divide both b and the sqrt().
You also need to check if discriminant >= 0 before doing so, because if it is negative there is no root and the above lines are going to fail.
Firstly, using namespace std was not used, so if you don't want to use it write std::court and std::cin. Secondly, the formula is b^2 -4ac so you need to put round brackets around b*b so that the answer is subtracted from -4ac. Then, you don't need to write else if for a==1 you can add it in the above condition as a>=1 and else put down a condition where discriminant is >=0 but a==0 which violates quadratic eq condition and you can write a cannot be equal to zero. Also, the main formula for x1 and x2 is wrong since the bracket should be applied around -b+sqroot(discriminant) so that the answer is then divided by multiplication of (2*a). Otherwise, what happens is that first sqrt is divided by 2 then multiplied by a and then added to -b.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
double roots() {
double a, b, c, x1, x2;
std::cout << "Enter quadratic equation in order (a, b, c): \n";
std::cin >> a >> b >> c;
double discriminant = (b * b)- (4 * a * c);
x1 = (-b + sqrt(discriminant)) / (2 * a);
x2 = (-b - sqrt(discriminant))/ (2 * a);
if (discriminant >= 0 && a >= 1) {
std::cout << "Your quadratic equation is " << a << "x^2 + " << b << " x
+ " << c << '\n';
std::cout << "x1 = " << x1 << '\n';
std::cout << "x2 = " << x2 << '\n';
}
else if (a==0){
std::cout << "a cannot be zero!";
exit(1);
}
else{
std::cout << "Negative value returned from (b2 - 4ac), please try again!";
exit(1);
}
}
int main() {
roots();
}

How does operator overloading work, and why doesn't it work in my case?

I've been provided a driver function that is supposed to demonstrate the results of operator overloading involving complex numbers. After reading up on overloading a while I managed to write the code in a way that it successfully compiles, however somewhere along the way the correct values are not being outputted by the program.
From what I understand overloading essentially works like a function. Objects are passed and the "function" can then do arithmetic/whatever with it and return a new object. Where I'm slightly lost though, is how overloading knows what values are being passed. For example, in my case I overloaded the "+" and "=" operators in order to add two complex numbers in the form "x = y + z". When the compiler comes across the "=" symbol, I'm assuming it simply passes whatever is on both the left and right side and passes those? Same with "+". In this case it would be passing "y" since it's the object on the left and "z" because it's the object on the right?
Here's my current "complex" class which includes the overloading definitions.
class Complex {
private:
double realPart;
double imaginaryPart;
public:
// friends
friend ostream & operator<<(ostream &out, const Complex &c);
friend istream & operator>>(istream &in, Complex &c);
// constructors
Complex()
{
realPart = 0;
imaginaryPart = 0;
}
Complex(double real)
{
realPart = real;
imaginaryPart = 0;
}
Complex(double real, double imaginary)
{
realPart = real;
imaginaryPart = imaginary;
}
// end of constructors
// + overloading
Complex operator+(Complex const &c)
{
Complex Add;
Add.realPart = realPart + c.realPart;
Add.imaginaryPart = imaginaryPart + c.imaginaryPart;
return Add;
}
// - overloading
Complex operator-(Complex const &c)
{
Complex Subtract;
Subtract.realPart = realPart - c.realPart;
Subtract.imaginaryPart = imaginaryPart - c.imaginaryPart;
return Subtract;
}
// * overloading
Complex operator*(Complex const &c)
{
Complex Multiply;
Multiply.realPart = (realPart * c.realPart) - (imaginaryPart * c.imaginaryPart);
Multiply.imaginaryPart = (realPart * c.imaginaryPart) - (imaginaryPart * c.realPart);
return Multiply;
}
// = overloading
Complex operator=(Complex const &c)
{
Complex Assignment;
Assignment.realPart = realPart;
Assignment.imaginaryPart = imaginaryPart;
return Assignment;
}
// == overloading
bool operator==(Complex const &c)
{
Complex Compare;
if (Compare.realPart == realPart && Compare.imaginaryPart == imaginaryPart)
{
return true;
}
else
{
return false;
}
}
// != overloading
bool operator!=(Complex const &c)
{
Complex NotEqual;
if (NotEqual.realPart == realPart && NotEqual.imaginaryPart == imaginaryPart)
{
return false;
}
else
{
return true;
}
}
};
// << overloading
ostream& operator<<(ostream& out, const Complex &c)
{
out << c.realPart;
if (c.imaginaryPart >= 0)
{
out << " + " << c.imaginaryPart << "i" << endl;
}
else
{
out << " - " << fabs (c.imaginaryPart) << "i" << endl;
}
return out;
}
// >> overloading
istream& operator>>(istream &in, Complex &c)
{
in >> c.realPart;
in >> c.imaginaryPart;
return in;
}
And here's the driver program:
int main()
{
for (double i = 1; i < 10; ++ i)
{
Complex y{i * 2.7, i + 3.2};
Complex z{i * 6, i + 8.3};
Complex x;
Complex k;
std::cout << "Enter a complex number in the form: (a, b)\n? ";
std::cin >> k; // demonstrating overloaded >>
std::cout << "x: " << x << "\ny: " << y << "\nz: " << z << "\nk: " << k << '\n'; // demonstrating overloaded <<
x = y + z; // demonstrating overloaded + and =
std::cout << "\nx = y + z:\n" << x << " = " << y << " + " << z << '\n';
x = y - z; // demonstrating overloaded - and =
std::cout << "\nx = y - z:\n" << x << " = " << y << " - " << z << '\n';
x = y * z; // demonstrating overloaded * and =
std::cout << "\nx = y * z:\n" << x << " = " << y << " * " << z << "\n\n";
if (x != k)
{ // demonstrating overloaded !=
std::cout << x << " != " << k << '\n';
}
std::cout << '\n';
x = k;
if (x == k)
{
// demonstrating overloaded ==
std::cout << x << " == " << k << '\n';
}
std::cout << std::endl;
}
}
Upon running, the problem seems to be with the object "x". Entering "5 2" will still output "x: 0 + 0i" This leads me to believe the issue is with either overloading of "=" or the stream operators. That said, I can't quite figure out why nothing is happening.
Is there an error in how I've constructed the "=" overloading definition as I think, or is it maybe something bigger I'm missing?
Your = is wrong; it should return *this.
Complex& operator=(Complex const &c)
{
realPart = c.realPart;
imaginaryPart = c.imaginaryPart;
return *this;
}
Fix that and most of the rest looks sane.
The operator=() is not correct: user Yakk - Adam has already shown you how to fix it. To give you insight on why it is wrong and what return *this does; let's look at your original function:
Complex operator=(Complex const &c) {
Complex Assignment;
Assignment.realPart = realPart;
Assignment.imaginaryPart = imaginaryPart;
return Assignment;
}
Here your signature takes a const reference to another Complex object this part is correct. Your return type is a Complex object this is in essence wrong because you don't want to return a copy of an object. The objective here is to perform assignment. This means you must make changes to the original LHS instance.
In the expression A = B + C; A is considered the LHS instance. Here you want to assign the expression (B + C) which are both RHS values.
So when Yakk - Adam showed you how to fix this by:
Complex& operator=(Complex const &c) {
realPart = c.realPart;
imaginaryPart = c.imaginaryPart;
return *this;
}
One of the differences here is that the return type is now a Reference to a specific object instead of a copy to an object.
Another difference is that there is no need to create a local temporary copy as you did in your original version:
Complex Assignment; // this is not needed
By removing that from operator=() he simply replaced these lines of code:
// Assignment.realPart = realPart; // To
realPart = c.realPart;
// Assignment.imaginaryPart = imaginaryPart; // To
imaginaryPart = c.imaginaryPart;
Here you are using the class's members directly and assigning to them the value that belongs to the other or c that is passed to the operator.
Then finally to return your LHS instance with the updated value; this is where you have to return a dereferenced this pointer.
What does *this mean? The this pointer is a special pointer that belongs to all class and struct types. For example any time you have class object:
class Foo {
public:
int bar { 10 };
void addFive();
};
You can use the this pointer directly in your member functions:
void Foo::addFive() {
this->bar += 5; // same as below (this) belongs to this particular instance.
// bar += 5;
}
Regarding your operator=(); since you are returning by reference you can not simply just return this. This will return the this pointer. We don't want a pointer to the object as we want a reference to the object; so we must deference the this pointer by returning *this.
I hope this helps clear things up for you.

Cannot retrieve data values from array quadraticExpression

So, in class for work we have to write a header class for quadratic expression. I have the header file done for the most part, however, when I proceed to run with the given .cpp file to test out the header file, it does not appear to read the values given in the array in the cpp file. When I debug, it just puts in garbage values for the values. To me I thought it made sense and can't see anything wrong with it. Unless am I missing something?
I constructed the following header file...
#pragma once
#include <cmath>
enum roots {
NO_ROOTS = 0,
ONE_ROOT = 1,
TWO_ROOTS = 2,
INFINITE_ROOTS = 3
};
class quadraticExpression
{
private:
double a, b, c;
public:
double evaluate(double x) const;
int getNumberOfRoots() const;
double getFirstRoot() const;
double getSecondRoot() const;
double getACoefficient() const;
double getBCoefficient() const;
double getCCoefficient() const;
quadraticExpression();
quadraticExpression(double a,
double b,
double c);
};
quadraticExpression::quadraticExpression()
{
a = 0;
b = 0;
c = 0;
}
inline quadraticExpression::quadraticExpression(double a, double b, double
c)
{
a = a;
b = b;
c = c;
}
;
double quadraticExpression::evaluate(double x) const
{
double y;
y = (a*(x * x)) + (b * x) + c;
return y;
}
int quadraticExpression::getNumberOfRoots() const
{
//return value from enum
double eins;
double zwei;
eins = getFirstRoot();
zwei = getSecondRoot();
if (eins == 0 && zwei == 0)
{
return TWO_ROOTS;
}
else if (eins == 0 || zwei == 0)
{
return ONE_ROOT;
}
else if (eins != 0 && zwei != 0)
{
return NO_ROOTS;
}
}
double quadraticExpression::getFirstRoot() const
{
//return one x value where y is 0
double root1 = (b * b);
double root2 = (4 * a*c);
double solutionOne;
double zUno;
zUno = (abs(b) + sqrt(root1 - root2)) / (2 * a);
solutionOne = (a*(zUno * zUno)) + (b * zUno) + c;
return solutionOne;
}
double quadraticExpression::getSecondRoot() const
{
//return another x value where y is 0
double root1 = (b * b);
double root2 = (4 * a*c);
double solutionTwo;
double zDos;
zDos = (abs(b) - sqrt(root1 - root2)) / (2 * a);
solutionTwo = (a*(zDos *zDos)) + (b *zDos) + c;
return solutionTwo;
}
double quadraticExpression::getACoefficient() const
{
return a;
}
double quadraticExpression::getBCoefficient() const
{
return b;
}
double quadraticExpression::getCCoefficient() const
{
return c;
}
And here is the .cpp tester file
#include <iostream>
#include "QuadraticExpression.h"
using namespace std;
void evaluateExpression(const quadraticExpression &);
int main()
{
quadraticExpression q[6] = { quadraticExpression(2.1, 3, -7),
quadraticExpression(1.4, 3.9, +7),
quadraticExpression(-.75, 0, 0),
quadraticExpression(0, .3, -7),
quadraticExpression(0, 0, 4),
quadraticExpression() };
for (int i = 0; i<6; i++)
evaluateExpression(q[i]);
return EXIT_SUCCESS;
}
void evaluateExpression(const quadraticExpression &q)
{
int errorsHandled = 0;
cout << q.getACoefficient() << " A " << endl;
cout << q.getBCoefficient() << " B " << endl;
cout << q.getCCoefficient() << " C " << endl;
cout << "f(-5) = " << q.evaluate(-5) << endl;
cout << "f(0) = " << q.evaluate(0) << endl;
cout << "f(5) = " << q.evaluate(5) << endl;
if (q.getNumberOfRoots() == INFINITE_ROOTS)
cout << "The Expression has Infinite Roots" << endl;
else if (q.getNumberOfRoots() == ONE_ROOT)
cout << "The Expression has One Root at x = " << q.getFirstRoot() <<
endl;
else if (q.getNumberOfRoots() == TWO_ROOTS)
{
cout << "The Expression has First Root at x = " << q.getFirstRoot() <<
endl;
cout << "The Expression has Second Root at x = " << q.getSecondRoot() <<
endl;
}
else
cout << "The Expression has No Roots" << endl;
try {
q.getFirstRoot();
}
catch (domain_error e) {
errorsHandled++;
}
try {
q.getSecondRoot();
}
catch (domain_error e) {
errorsHandled++;
}
cout << "Errors Handled: " << errorsHandled << endl;
cout << endl;
cout << endl;
}
I fathom I might not be properly acquiring the data values a, b, and c from the array given in the cpp file therefore it just collects garbage values, however I'm stumped here.
This won't work as you intend.
inline quadraticExpression::quadraticExpression(double a, double b, double c)
{
a = a;
b = b;
c = c;
}
You're just assigning the parameter variables to themselves, not assigning to the member variables of the class. Variables declared in a function take precedence over member variables with the same name.
You should give the parameters different names from the member variables, or assign like this->a = a;.
But if you're just initializing member variables from parameters, you don't need to do assignments at all, initializer lists are preferred (see C++: Where to initialize variables in constructor):
quadraticExpression::quadraticExpression(double a, double b, double c) : a(a), b(b), c(c)
{}
Similarly, the constructor with no arguments should use an initializer list:
quadraticExpression::quadraticExpression() : a(0), b(0), c(0)
{}

Don't print variable if it's zero

double a, b, c, d, x, y;
char operation
cout << setw(6) << a << b
<< setw(3) << operation
<< setw(6) << c << d
<< " = "
<< setw(6) << x << y
<< endl;
I'm making a calculator which takes two complex numbers and adds subtracts etc. My question is how do I format my output so that 0's are not displayed.
I.E. if the input is (a+bi)(c+di) the output is a+bi * c+di = x+yi But a, b, c, d, x, y are only displayed if they are nonzero.
I know I can do it with if statements and stuff but I was hoping there's a shorter, more efficient, path.
I don't think you can avoid doing the condition and printing if non-zero somewhere.
About all you can do is wrap it up so most code doesn't need to deal with it:
class complex {
double x;
double i;
public:
// ...
friend std::ostream &operator<<(std::ostream &os, complex const &c) {
// if both parts are 0, we probably want to print *something*
if (c.x == 0.0 && c.i == 0.0)
return os << 0;
if (c.x != 0.0)
os << c.x;
if (c.i != 0.0)
os << c.i << "i";
return os;
}
};
complex a, b, c;
// ...
cout << a << operation << b << " = " c << "\n";
You'll have to add a little more if you want this to honor (for example) width/precision correctly (though for real use, you undoubtedly want to use the complex class that's already in the standard library instead).
Yes, you can do it by including <complex>
std::complex<double> com_one; // value 0 + 0i
std::complex<double> com_two(3.14); // value 3.14 + 0i
std::complex<double> com_three(1.5, 3.14) // value 1.5 + 3.14i
std::complex<double> com_four(com_two); // value is also 3.14 + 0i
Then to use arithmetic operations, you can just use
std::cout << com_one + com_two << std::endl;
std::cout << com_one - 3.14 << std::endl;
std::cout << 2.75 * com_two << std::endl;
com_one += com_three / 2.0;
Source: http://stdcxx.apache.org/doc/stdlibug/20-2.html
For checking if it's a zero check it using if, and compare it with a zero. This is the most clean technique.

Newton method for computing an inverse

This is following the question I asked in this thread : Link error missing vtable
I defined a class 'function' and two others classes 'polynomial' and 'affine' that inherit from 'function'.
class function {
public:
function(){};
virtual function* clone()const=0;
virtual float operator()(float x)const=0; //gives the image of a number by the function
virtual function* derivative()const=0;
virtual float inverse(float y)const=0;
virtual ~function(){}
};
class polynomial : public function {
protected:
int degree;
private:
float *coefficient;
public:
polynomial(int d);
virtual~polynomial();
virtual function* clone()const;
int get_degree()const;
float operator[](int i)const; //reads coefficient number i
float& operator[](int i); //updates coefficient number i
virtual float operator()(float x)const;
virtual function* derivative()const;
virtual float inverse(float y)const;
};
class affine : public polynomial {
int a;
int b;
//ax+b
public:
affine(int d,float a_, float b_);
function* clone()const;
float operator()(float x)const;
function* derivative()const;
float inverse(float y)const;
~affine(){}
};
Method inverse in polyomial does not seem to work fine. It is based on the Newton method applied to the function x->f(x)-y for fixed y (the element for which we're computing the inverse) and the current polynomial f.
float polynomial::inverse(float y)const
{
int i=0;
float x0=1;
function* deriv=derivative();
float x1=x0+(y-operator()(x0))/(deriv->operator()(x0));
while(i<=100 && abs(x1-x0)>1e-5)
{
x0=x1;
x1=x0+(y-operator()(x0))/(deriv->operator()(x0));
i++;
}
if(abs(x1-x0)<=1e-5)
{
//delete deriv; //I get memory problems when I uncomment this line
return x1;
}
else
{
cout<<"Maximum iteration reached in polynomial method 'inverse'"<<endl;
//delete deriv; //same here
return -1;
}
}
double polynomial::operator()(double x)const
{
double value=0;
for(int i=0;i<=degree;i++) value+=coefficient[i]*pow(x,i);
return value;
}
polynomial* polynomial::derivative()const
{
if(degree==0)
{
return new affine(0,0,0);
}
polynomial* deriv=new polynomial(degree-1);
for(int i=0;i<degree;i++)
deriv[i]=(i+1)*coefficient[i+1];
return deriv;
}
I test this method with p:x->x^3 :
#include "function.h"
int main(int argc, const char * argv[])
{
polynomial p(3);
for(int i=0;i<=2;i++) p[i]=0;
p[3]=1;
cout<<"27^(1/3)="<<p.inverse(27);
return 0;
}
This script outputs 27^(1/3)=Maximum iteration reached in polynomial method 'inverse'
-1 even if I put 10,000 instead of 100. I've read some articles on the internet and it seems that it's a common way to compute the inverse.
the abs function prototype is: int abs(int)
So a test like abs(x1-x0)<=1e-5 won't behave as you expect; you compare a int with a float. In this case the float will be converted to int so it the same as abs(x1-x0)<=0
This is probably why you don't get the expected result - I suggest adding a few more printouts to get to the bottom of things.
Well, the problem was in method 'derivative'. Instead of using the 'operator[]' that I redefined, I used '->coefficient[]' and the main script worked fine for p.inverse(27) (only 14 iterations). I just replaced deriv[i]=(i+1)*coefficient[i+1]; with deriv->coefficient[i]=(i+1)*coefficient[i+1];
Check This Code :
#include<iostream>
#include<cmath>
#include<math.h>
using namespace std;
void c_equation(int choose, double x);
void Processes(double x, double fx1, double fdx1, int choose);
void main()
{
int choose,choose2;
double x;
system("color A");
cout << " " << endl;
cout << "=============================================================" << endl;
cout << "Choose Equation : " << endl;
cout << "_____________________________________" << endl;
cout << "1- x-2sin(x)" << endl;
cout << "2- x^2 + 10 cos(x)" << endl;
cout << "3- e^x - 3x^2" << endl;
cout << " " << endl;
cin >> choose;
cout << "If you have values press 1/ random press 2 :" << endl;
cin >> choose2;
if (choose2 == 1)
{
cout << " " << endl;
cout << "Enter Xo : " << endl;
cin >> x;
c_equation(choose, x);
}
else if (choose2 == 2)
{
x = rand() % 20;
cout << "Xo = " << x << endl;
c_equation(choose, x);
choose2 = NULL;
}
else
{
cout << "Worng Choice !! " << endl;
choose = NULL;
choose2 = NULL;
main();
}
}
void c_equation(int choose, double x)
{
double fx;
double fdx;
double fddx;
double result;
if (choose == 1)
{
fx = x - 2 * sin(x);
fdx = 1 - 2 * cos(x);
fddx = 2 * sin(x);
result = abs((fx * fddx) / pow(fdx, 2));
}
else if (choose == 2)
{
fx = pow(x, 2) + 10 * cos(x);
fdx = 2 * x - 10 * sin(x);
fddx = 2 - 10 * cos(x);
result = abs((fx * fddx) / pow(fdx, 2));
}
else if (choose == 3)
{
fx = exp(x) - 3 * pow(x, 2);
fdx = exp(x) - 6 * x;
fddx = exp(x) - 6;
result = abs((fx * fddx) / pow(fdx, 2));
}
else
{
cout << " " << endl;
}
//------------------------------------------------------------
if (result < 1)
{
cout << "True Equation :) " << endl;
Processes(x, fx, fdx , choose);
}
else
{
system("cls");
cout << "False Equation !!" << endl;
choose = NULL;
x = NULL;
main();
}
}
void Processes(double x, double fx, double fdx , int choose)
{
double xic;
for (int i = 0; i < 3; i++)
{
xic = x - (fx / fdx);
cout << " " << endl;
cout << "Xi = " << x << " " << "F(Xi) = " << fx << " " << " F'(Xi) = " << fdx << " " << " Xi+1 = " << xic << endl;
x = xic;
if (choose == 1)
{
fx = xic - 2 * sin(xic);
fdx = 1 - 2 * cos(xic);
}
else if (choose == 2)
{
fx = pow(xic, 2) + 10 * cos(xic);
fdx = 2 * xic - 10 * sin(xic);
}
else if (choose == 3)
{
fx = exp(xic) - 3 * pow(xic, 2);
fdx = exp(xic) - 6 * xic;
}
}
}