Reputation: 29
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;
}
Upvotes: 0
Views: 600
Reputation: 881323
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:
add
, sub
, and so on, when you can just use the built-in operators.(2+0i)
.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
Upvotes: 5