complex number wrong output - c++

I write this code with a class named Complex with the following methods:
a. Complex() // Default constructor returning 0
b. Complex(float im, float real)
c. float getImaginary() const
d. float getReal() const
e. Complex add(const Complex& rhs) const
f. Complex subtract(const Complex& rhs) const
g. Complex multiply(const Complex& rhs) const
#include <iostream>
using namespace std;
class Complex {
private:
float real;
float imaginary;
public:
Complex();
Complex(float real=0, float im=0);
float GetReal() const;
float GetImaginary() const;
Complex Add(const Complex &rhs) const;
Complex Subtract(const Complex &rhs) const;
Complex Multiply(const Complex &rhs) const;
void SetReal(float r);
void SetImaginary(float i);
};
Complex::Complex()
{
real=imaginary=0;
}
Complex::Complex(float realpart, float imaginarypart)
{
SetReal(real);
SetImaginary(imaginarypart);
}
void Complex::SetReal(float r)
{
real = r;
}
void Complex::SetImaginary(float i)
{
imaginary = i;
}
float Complex::GetReal() const
{
return real;
}
float Complex::GetImaginary() const {
return imaginary;
}
Complex Complex::Add(const Complex &rhs) const {
return Complex(GetReal() + rhs.GetReal(), GetImaginary() + rhs.GetImaginary());
}
Complex operator+(const Complex &rhs1, const Complex &rhs2) {
return rhs1.Add(rhs2);
}
Complex Complex::Subtract(const Complex &rhs) const
{
return Complex(GetReal() - rhs.GetReal(), GetImaginary() - rhs.GetImaginary());
}
Complex operator-(const Complex &rhs1, const Complex &rhs2)
{
return rhs1.Subtract(rhs2);
}
Complex Complex::Multiply(const Complex &rhs) const
{
return Complex(GetReal() * rhs.GetReal(), GetImaginary() * rhs.GetImaginary());
}
Complex operator*(const Complex &rhs1, const Complex &rhs2)
{
return rhs1.Multiply(rhs2);
}
int main()
{
Complex c();
Complex x(-2,4);
Complex y(5,6);
Complex z = x + y;
cout << z.GetReal() << '+' << z.GetImaginary() << 'i' << endl;
Complex e = x - y;
cout << e.GetReal() << '+' << e.GetImaginary() << 'i' << endl;
Complex r = x * y;
cout << r.GetReal() << '*' << r.GetImaginary() << 'i' << endl;
return 0;
}
but i take these output
8.99944e-039+10i
8.99944e-039+-2i
8.99944e-039*24i
Can somebody help me for this error ?

3 issues in your code:
Complex::Complex(float realpart, float imaginarypart)
{
SetReal(realpart);
SetImaginary(imaginarypart);
}
causes the warning:
<source>:24:28: warning: unused parameter 'realpart' [-Wunused-parameter]
24 | Complex::Complex(float realpart, float imaginarypart)
|
Fix it by passing realpart to SetReal or rather use the member initializer list:
Complex::Complex(float realpart, float imaginarypart) : real(realpart),imaginary(imaginarypart)
{}
Next, this:
Complex c();
is the most vexing parse. It declares a function named c taking no parameters and retuning a Complex. It is not declaring a variable c of type Complex. Write
Complex c;
Complex c{};
to call the default constructor. However, you class has two default constructors:
Complex();
Complex(float real=0, float im=0);
A default constructor is one that can be called without parameters and thats the case for both of these. Hence you currently cannot default construct a Complex, the constructors are ambigoous. I read your assignemnt as requiring you to provide two constructors:
Complex();
Complex(float real, float im); // no defaults !!
Then you will be able to default construct a Complex via Complex c; or Complex c{}; (but not via Complex c(); because thats a function declaration).
After fixing those, I get almost reasonable looking output: https://godbolt.org/z/x4xG8xzTf
Finally, your formula for multipliying two complex numbers is wrong. I'll leave that for you to fix it.

Related

Changing type of template at run time

I'm trying to make a Matrix struct which would work with various data types, including my Complex struct:
struct Complex {
double re = 0, im = 0;
Complex operator*(const Complex& other) const {
return Complex(re * other.re - im * other.im, im * other.re + re * other.im);
}
Complex operator*(const double& other) const {
return Complex(re * other, im * other);
}
Complex() {}
Complex(double a) : re(a) {}
Complex(double a, double b) : re(a), im(b) {}
};
std::ostream& operator<<(std::ostream& out, Complex z) {
out << z.re << " " << z.im << "i";
return out;
}
template <typename T>
Complex operator*(const T& c, const Complex& z) {
return z * c;
}
The obvious way is to make a template like one in the code below:
template <typename T>
struct Matrix {
std::vector<T> m;
unsigned int rows, cols;
Matrix<Complex> operator*(const Complex& z) const {
Matrix<Complex> result(rows, cols);
for (int i = 0; i < m.size(); i++) {
result.m[i] = m[i] * z;
}
return result;
}
void operator*=(const Complex& z) {
(*this) = (*this) * z; // <- ideally we're trying to get this to work
}
void operator=(const Matrix<T>& other) {
rows = other.rows;
cols = other.cols;
m.resize(rows * cols);
m = other.m;
}
Matrix(const unsigned int& rows, const unsigned int& cols) : rows(rows), cols(cols) {
m.resize(rows * cols);
}
Matrix(const Matrix<T>& other) : rows(other.rows), cols(other.cols) {
(*this) = other;
}
};
int main() {
Complex z(1, 1);
Matrix<double> A(1, 1);
A.m[0] = 2.0;
std::cout << (A * z).m[0] << std::endl; // works as it should because a temporary Matrix<Complex> gets created
A *= z; // and here we're introducing the problem
std::cout << A.m[0] << std::endl;
}
The problem arises when calling *= operator. We're trying to call an unexisting = operator overload. My first attempt was to write something like this instead:
template <typename T_other>
void operator=(const Matrix<T_other>& other) {
rows = other.rows;
cols = other.cols;
m.resize(rows * cols);
for (int i = 0; i < m.size(); i++) {
m[i] = other.m[i];
}
}
This however leads to other problems:
The type of A is still Matrix<double> and after the multiplication it should be Matrix<Complex> to store complex numbers.
There is no conversion from Complex to double as it results in loss of data (the imaginary part).
Also, I would like to avoid creating a template specialization for Matrix<Complex>, but if there's no other way I'll accept it.
C++ is statically typed. Once you declare a variable and type, you can't change the type of that variable.
template <typename T>
struct Matrix {
void operator*=(const Complex& z) {
(*this) = (*this) * z;
}
}
The *= operator overload for your Matrix doesn't make sense. A Complex can hold the value of a double with imaginary part 0, but a double can never hold the value of a Complex.
Multiplying a real matrix by a complex number necessarily produces a complex matrix. So you try and assign the complex RHS to the real LHS - and either that makes no sense and shouldn't be done, or you have some idea for how to convert that (e.g. keep real part, keep absolute value etc) and then have to implement a Matrix<double> constructor from Matrix<Complex>.
Real numbers are a subset of complex numbers, so just make A a Matrix<Complex> from the beginning if you ever want to make it complex later.

Can you Avoid Multiple Operator Overloads for Mathematical Operators?

Say I have a very simple Rational class like the one below:
class Rational
{
int numer;
int denom;
public:
Rational(const int& numer, const int& denom) : numer(numer), denom(denom) {}
void operator*(const Rational& other) { std::cout << "multiply, simple as\n"; }
}
All well and good. Then say that I want to be able to multiply my Rational class with an integer, so I add another function to the class:
class Rational
{
int numer;
int denom;
public:
Rational(const int& numer, const int& denom) : numer(numer), denom(denom) {}
void operator*(const Rational& other) { std::cout << "multiply, simple as\n"; }
void operator*(const int& other) { std::cout << "some math here\n"; }
}
Ok no big deal. Except that I can't actually do the following because the order of the parameters would be all wrong:
Rational mine(1, 2);
const Rational result = 2 * mine;
Ok, one more iteration and I have the following:
class Rational
{
int numer;
int denom;
public:
Rational(const int& numer, const int& denom) : numer(numer), denom(denom) {}
void operator*(const Rational& other) { std::cout << "multiply, simple as\n"; }
void operator*(const int& other) { std::cout << "some math here\n"; }
friend void operator*(const int& other, const Rational& mine) { std::cout << "even more math here\n"; }
}
What I'm trying to find out is if there's a way that I can avoid having to write the same function twice for every mathematical operation that I'd want my class to support, just so that I can call it with the arguments in whatever order I want. This may well just be how you have to implement this sort of thing within C++'s type system, but it seems a tad annoying to have to add this boilerplate for every mathematical operation that you want your class to support.
The issue with having a single function is that the type of the left and right operands to * would vary (and you would have to use them differently).
This can be solved by fixing both of the argument types to Rational and creating an implicit conversion from an int x to Rational x/1 (which is probably desirable anyways). This way, in 2 * mine, the 2 will implicitly be converted to Rational(2, 1) * mine.
Here's an example:
class Rational
{
int numer;
int denom;
public:
// default argument of denom=1 allows implicit conversion from int
Rational(int numer, int denom = 1) : numer(numer), denom(denom) {}
friend Rational operator*(const Rational& l, const Rational& r) {
std::cout << "Rational(" << l.numer << ", " << l.denom
<< ") * Rational(" << r.numer << ", " << r.denom << ")\n";
// calculate and return result
}
friend Rational operator/(const Rational& l, const Rational& r) { /* ... */ }
friend bool operator==(const Rational& l, const Rational& r) { /* ... */ }
};

Question about class complex in the page 61 of book c++ programming language

class complex {
double re, im; // representation: two doubles
public:
complex(double r, double i) :re{r}, im{i} {} // construct complex from two scalars
complex(double r) :re{r}, im{0} {} // construct complex from one scalar
complex() :re{0}, im{0} {} // default complex: {0,0}
double real() const { return re; }
void real(double d) { re=d; }
double imag() const { return im; }
void imag(double d) { im=d; }
complex& operator+=(complex z) { re+=z.re , im+=z.im; return ∗this; } // add to re and im
// and return the result
complex& operator−=(complex z) { re−=z.re , im−=z.im; return ∗this; }
complex& operator∗=(complex); // defined out-of-class somewhere
complex& operator/=(complex); // defined out-of-class somewhere
};
In my opinion, the format of function declaration should look like that, (return type) name (argument){}. In this case,
complex& operator+=(complex z) { re+=z.re , im+=z.im; return ∗this; }
The complex& is the return type and operation+ is the function name, but why it is followed by a "="?
With operator + you can do something like:
c = a + b;
whti operator += is used to add some data and store it in the first summand:
a += b;
operator+= is itself a function.
The following expression
com_num+=com_other;
is equivalent to the call.
com_num.operator+=(com_other);

How to set precision for complex numbers in C++

I have the following code where I need to add two complex numbers. Formula is working, however, I am not able to get rid of the scientific notation. I'm new to C++, and not sure how to use setPrecision.
My code in .hpp:
class ComplexNumber
{
public:
//--constructors
ComplexNumber();
ComplexNumber(double r, double i);
ComplexNumber(const ComplexNumber &cn);
void print();
ComplexNumber add(const ComplexNumber &rhs);
private:
double re, im;
};
My code in .cpp file
//--constructors
ComplexNumber::ComplexNumber()
{
}
ComplexNumber::ComplexNumber(double r, double i)
{
}
ComplexNumber::ComplexNumber(const ComplexNumber &cn)
{
}
void ComplexNumber::print()
{
std::cout << this->re << " + " << this->im << "i" << std::endl;
}
ComplexNumber ComplexNumber::add(const ComplexNumber &rhs)
{
return ComplexNumber(this-> re + rhs.re, this->im + rhs.im);
}
My main:
int main(int argc, const char * argv[]) {
ComplexNumber a(1,2);
ComplexNumber b(3,4);
ComplexNumber c;
c = a.add(b);
c.print();
return 0;
}
Output:
4.94066e-324 + 6.95322e-310i
it should be 4 + 6i
None of your constructors actually do anything. That means the member variables will be uninitialized, their values will be indeterminate and using them will lead to undefined behavior
You need to actually initialize the members in the constructors.
Works as expected after fixing the syntax (making it an aggregate):
#include <iostream>
struct ComplexNumber
{
void print();
ComplexNumber add(const ComplexNumber &rhs);
double re, im;
};
void ComplexNumber::print()
{
std::cout << this->re << " + " << this->im << "i" << std::endl;
}
ComplexNumber ComplexNumber::add(const ComplexNumber &rhs)
{
return ComplexNumber{this-> re + rhs.re, this->im + rhs.im};
}
int main(int argc, const char * argv[]) {
ComplexNumber a{1,2};
ComplexNumber b{3,4};
ComplexNumber c;
c = a.add(b);
c.print();
return 0;
}
Precision is not the issue here.
Your two-argument constructor needs to be implemented as follows
ComplexNumber::ComplexNumber(double r, double i) : re(r), im(i)
{
}
otherwise the class members stay uninitialised.
Reading uninitialised variables is undefined behaviour in C++; your output is a manifestation of that.
It's stylistically acceptable (and in my opinion preferable for a number class) to write
ComplexNumber() = default;
for your default constructor; if you want it to keep the class members uninitialised, as is the case for the C++ built-in types. Just don't read the member variables before assigning them to something.
Finally, rely on the compiler to generate the copy constructor for you: there's no need to build your own.

Overload operators to work with class objects?

How can I modify the following code in such way I don't need to repeat f2=11;
f3=12; in the main function. The code is for overloading the most common operators.
class FLOAT{
private:
float x;
public:
FLOAT(){ x=0.0; }
void setFloat(float f) { x=f; }
float getFloat() { return x;};
FLOAT operator+(FLOAT obj) {x=x+obj.x; return *this;};
FLOAT operator-(FLOAT obj) {x=x-obj.x; return *this;};
FLOAT operator*(FLOAT obj) {x=x*obj.x; return *this;};
FLOAT operator/(FLOAT obj) {x=x/obj.x; return *this;};
FLOAT& operator=(const FLOAT& obj) {this->x=obj.x; return *this; };
FLOAT& operator=(const float& y) {this->x=y; return *this; };
};
int main() {
FLOAT f,f2,f3;
f2=11;
f3=12;
f=f3-f2;
cout<<"f3-f2 ="<<f.getFloat()<<endl;
f2=11;
f3=12;
f=f3+f2;
cout<<"f3+f2 ="<<f.getFloat()<<endl;
f2=11;
f3=12;
f=f3*f2;
cout<<"f3*f2 ="<<f.getFloat()<<endl;
f2=11;
f3=12;
f=f3/f2;
cout<<"f3/f2 ="<<f.getFloat()<<endl;
system("pause"); // to pause console screen
return 0;
}
#Oli's answer pretty much says you what minimal thing you need to do in order to make your code work. However, I see (and I know even #Oli sees) that your implementation of the class has many flaws.
Since you've implemented FLOAT, I'm explaining you the implementation of Double (the implementation of FLOAT would be similar).
class Double {
double data;
public:
Double (double p=0.0) : data(p){}
double value() { return data; }
Double & operator+=(Double const & other)
{
data += other.data;
return *this;
}
Double & operator-=(Double const & other)
{
data -= other.data;
return *this;
}
//...
};
Note that you don't need to implement operator=(Double const&) and Double(Double const&). The compiler generated ones would be enough. Since the constructor takes one argument of type double, you don't need to implement operator=(double const &) also. The compiler generated copy-semantics, along with the constructor, would take care of that.
Now see this,
//implement operator+ and operator- as non-member functions
Double operator+(Double a, Double const & b)
{
a += b; //a is local copy, so we can change it
return a;
}
Double operator-(Double a, Double const & b)
{
a -= b; //a is local copy, so we can change it
return a;
}
Note that I've implemented operator+ and operator- in terms of operator+= and operator-= respectively.
Similarly, you can implement operator/= and operator*= as member functions, and then implement operator/ and operator* in terms of the them!
Your operators should create a new instance; they shouldn't be modifying themselves (in fact, they should be declared const to prevent this).
e.g.:
FLOAT operator+(FLOAT obj) const
{
FLOAT tmp;
tmp.setFloat(x + obj.x);
return tmp;
}
Note there are much more idiomatic ways of defining operator overloads (e.g. defining operator+ in terms of operator+=, and defining a constructor that takes a float). But the above should suffice.