Overloading c++ operators int/float(..) - c++

I'm working on operators in C++ now, but i have one problem. Well I'm trying to overloard int/float operators, I have 2 variables in class
class Zespolona{
public:
float re;
float im;
}
I've done all of my operators but when i do
operator int const(){
this->re = (int)this->re;
this->im = (int)this->im;
return *this;
}
then it gets an infinite loop.
My main
int main(){
Zespolona z1;
z1.re = 1.2;
z1.im = 34.9;
z1 = (int)z1;
cout << z1 << endl;
}
What can i do, to get int of two of those variables?

I am not completely sure what you are trying to achieve. I am guessing one of the following two possibilities:
1) Covert the two floats of your class (re, im) into integers:
This is rather simple. Since the two members are public you can access them directly:
#include <iostream>
int main()
{
Zespolona Z1;
Z1.re = 1.2;
Z1.im = 34.9;
std::cout << "Re: " << (int) Z1.re << std::endl;
std::cout << "Im: " << (int) Z1.im << std::endl;
return 0;
}
The output of this program should be:
Re: 1
Im: 34
Note: When you convert a float to an integer everything after the decimal dot is omitted (at least that is the behavior using g++ under Ubuntu).
If you want the two floats to be private or protected you would have to create methods like int GetRe() and int GetIm().
2) Convert the two floats of your class (re, im) into one integer using the integer conversion operator operator int const(). This operator has to return exactly one int. For the following example I decided to return the absolute value (magnitude) of the complex number (since your members are called re and im I am guessing the class is used for complex numbers):
class Zespolona
{
public:
float re;
float im;
operator int const()
{
return (int) sqrt(re*re + im*im);
}
};
int main()
{
Zespolona Z1;
Z1.re = 1.2;
Z1.im = 34.9;
std::cout << "Z1: " << (int) Z1 << std::endl;
return 0;
}
The output should now be:
Z1: 34
Note: Again the correct (float) result 34.92... is converted into the integer 34.
The code you mentioned in your questions returns a reference to your class Zespolona when you try to convert it into int. Thus, the compiler again tries to convert that reference into an int. But all it gets is again a reference to Zespolona, and so on. Hence, you get an infinite loop.

Related

I wrote a class. And when I specified the function, it failed

class equation
{
public :
int k;
int l;
int t;
float x1_value;
float x2_value;
float b1 = sqrt(l^2 -4*k*t);
float equation1;
equation();
~equation();
};
float void equation::equation1() {
if (b1 == 0)
{
float x1_value = -l/2*k;
cout << " joongen. " <<x1_value <<endl;
}
else if (b1 > 0)
{
float x1_value = ((-l + sqrt(b1) / (2*k));
float x2_value = ((-l - sqrt(b1) / (2*k));
cout << "x is 2"<< x1_value < " x 2 is "<< x2_value <<endl;
}
else
{
cout <<"imagine number ."<<endl;
}
return (0);
};
The code produces this error:
error: two or more data types in declaration of 'equation1'
float void equation::equation1() {
^
I can make out two problems.
First you define equation1 as a member variable with type float. You might want to change that into a function declaration.
// ...
float equation1();
// ...
The second problem is pointed out in the comments. If you implement your function, you should only use one return type. As I can only guess, what return type you would really want, I take float, since it is in your faulty function declaration.
// ...
float equation::equation1() {
// ...
}
// ...
One extra thing, that disturbs me every time I see someone who is new with C++. Please, please, please, don't use using namespace std;. I assume you do so, because of the missing std::. You open up an fastly huge namespace. You may end up defining a function, with the same name and parameters and encounter a very cryptic error, which is nearly impossible to figure out.

I'm getting a conversion error in my C++ solution for TSP

I am attempting to solve TSP in C++ with a multidimensional array and am receiving an error message about type conversion.
I've gotten rusty on C++ having not used it in a few years, so to relearn I decided to try a few Travelling Salesman solutions. The first I'm using uses a multidimensional array to store the points, which are being assigned randomly. That part worked fine, so I moved on to the distance formula. I created a helper function for the basic distance formula that takes 2 arrays as its input which functions fine on its own, then created a function to find the total distance of a full array of cities. It takes in an array of doubles and an integer that represents the total number of cities, then iterates through the array finding the distance for each point and adding them together.
Here's the variable declaration and random point assignment
int numCities = 10;
double cities[numCities][2];
//Creates random(unseeded) points
for(int i = 0; i < numCities; i++){
for(int j = 0; j < 2; j++){
cities[i][j] = (rand() % 100) + 1;
}
}
Here's the line being used to call the function
cout << distTotal(cities, numCities) << endl;
And here's the function and helper function
//basic distance formula
double cityDist(double cityA[], double cityB[]){
return sqrt(pow((cityB[0]-cityA[0]), 2.0)+
pow((cityB[1]-cityA[1]), 2.0));
}
//calculate total distance of group of cities
double distTotal(double* points[], int num){
double total = 0;
for(int i = 0; i < num-1; i++){
total=total+cityDist(points[i], points[i+1]);
}
return total;
}
So ideally this should be giving me the total distance between all the points in the base order given here. However, I'm currently getting the following error:
error: cannot convert 'double (*)[2]' to 'double**' for argument '1' to 'double distTotal(double**, int)'
If I remember correctly, this could have to do with pointers, but I honestly don't remember enough about C++ pointers to know how to fix it.
Any help is appreciated, thanks
Your declaration should be double* points as C-arrays decay into pointers. If doing c++ you might consider using std::vector<double>& as an input instead.
Edit: if you end up using c-arrays you will have to allocate them on the heap and free the resources.
int numCities = 10;
double cities[numCities][2];
Instead of having an anonymous pair of doubles containing the x and y position of each city, create a class/struct for it. It'll make it easier to expand your solution later. If you'd like to store the name of the city with its position for example:
struct position_t {
double x;
double y;
};
struct city_t {
position_t position;
std::string name;
};
Then, instead of having a fixed number of cities in an array, consider using a vector which can grow and shrink dynamically during runtime:
std::vector<city_t> cities;
With some helper functions added:
#include <cmath>
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
struct position_t {
position_t(double X, double Y) : x(X), y(Y) {}
double dist(const position_t& other) const {
return std::sqrt(std::pow(x - other.x, 2.) + std::pow(y - other.y, 2.));
}
// a function to print the position
friend std::ostream& operator<<(std::ostream&, const position_t&);
double x;
double y;
};
std::ostream& operator<<(std::ostream& os, const position_t& p) {
return os << '{' << p.x << ',' << p.y << '}';
}
struct city_t {
city_t(const position_t& p, const std::string_view& n) : position(p), name(n) {}
double dist(const city_t& other) const {
// this distance function just calls the function in the position_t
return position.dist(other.position);
}
// a function to print the values of the city
friend std::ostream& operator<<(std::ostream&, const city_t&);
position_t position;
std::string name;
};
std::ostream& operator<<(std::ostream& os, const city_t& c) {
return os << c.position << ' ' << c.name;
}
int main() {
std::vector<city_t> cities = {{{10., 20.}, "Ankeborg"},
{{11., 12.}, "Gothenburg"}};
for(const auto& c : cities) {
std::cout << c << "\n";
}
std::cout << "distance: " << cities[0].dist(cities[1]) << "\n";
}
Output:
{10,20} Ankeborg
{11,12} Gothenburg
distance: 8.06226

Condensing functions to go two ways in C++

Apparently, I should be able to condense these six functions into three simpler functions that go two ways, using bool logic, but I have no idea where to start!
void footToMeter(int inputfeet) {
double outputMeter = ((inputfeet) / (3.281));
cout << outputMeter;
}
void meterToFoot(int inputmeter) {
double outputFoot = ((inputmeter)*(3.281));
cout << outputFoot;
}
void CtoF(int inputC) {
double outputF = 32 + (inputC*(9.0 / 5.0));
cout << outputF;
}
void FtoC(int inputF) {
double outputC = (5.0 / 9)*(inputF - 32);
cout << outputC;
}
void cMtocF(int inputcM) {
double outputcF = ((inputcM)*(35.315));
cout << outputcF;
}
void cFtocM(int inputcF) {
double outputcM = ((inputcF) / (35.315));
cout << outputcM;
}
One approach would be to add an extra parameter for each function to determine which direction you want to convert.
Example:
void lengthConversion(int inputLength, bool toFeet)
{
double output;
if (toFeet)
output = inputLength * 3.281;
else
output = inputLength / 3.281
cout << output;
}
#forthe has a point though - enum would make it a bit nicer.
To make it into 3 simpler functions. First try and bundle up the similarities between the current functions:
// Put the foot to meter and meter to foot functions into one, with 2 extra boolean values.
void fAndMConversion(int measurement , bool footToMeter , bool meterToFoot) {
if(footToMeter){
double fTm = ((measurement) / (3.281));
cout << fTm;
}
if(meterToFoot){
double mTf = ((measurement)*(3.281));
cout << mTf;
}
}
These are the first two functions. This also allows us to get foot to meter and meter to foot conversion in one call to the function: fAndMConversion(11 , true , true). You can bundle it up even further into a conversions() function with 7 args in total, 6 being booleans.

C++ beginner: Trying to incorporate two functions into one

The addComplex() function is meant to accept two Complex objects and return a Complex object. The real and imaginary parts of the returned object should be the sum of the real and imaginary parts of the two objects passed to addComplex(). Of course, as you can see, I can only get it to return the sum of the real parts. How do I include the imaginary parts within the function?
This is homework that I've been working on for almost 2 hours and am coming up against a wall. Any help in the right direction is appreciated.
My code:
#include <iostream>
#include <cmath>
using namespace std;
// class declaration section
class Complex
{
// friends list
friend double addComplex(Complex&, Complex&);
private:
double real;
double imag;
public:
Complex(double = 0, double = 0); // constructor
void display();
};
// class implementation section
Complex::Complex(double rl, double im)
{
real = rl;
imag = im;
}
void Complex::display()
{
char sign = '+';
if(imag < 0) sign = '-';
cout << real << sign << abs(imag) << 'i';
return;
}
// friend implementations
double addComplex(Complex &a, Complex &b)
{
return (a.real + b.real);
}
int main()
{
Complex a(3.2, 5.6), b(1.1, -8.4);
double num;
cout << "The first complex number is ";
a.display();
cout << "\n\nThe second complex number is ";
b.display();
cout << "\n\nThe sum of these two complex numbers is ";
num = addComplex(a,b);
Complex c(num);
c.display();
cout << "\n\nThis is the end of the program.\n";
return 0;
}
You need to return a Complex object, not a double.
As far as some code quality tips, you should create a constant accessor instead of making it a friend function. Also, the references should be const since you aren't modifying the inputs. And using std is often considered poor practice, though it's not so bad in a non-header file.
Complex addComplex(const Complex& a, const Complex& b)
{
return Complex(a.real + b.real, a.imag + b.imag);
}
Complex addComplex(Complex &a, Complex &b)
{
return Complex(a.real + b.real, a.imag + b.imag);
}
You might also want to consider making the 'addComplex' function be an overload of the '+' operator.
addComplex should return a Complex object:
Complex addComplex(const Complex &a, const Complex &b)
{
/*Sum the real and imaginary parts, and use the constructor*/
return Complex(a.real + b.real, a.imag + b.imag);
}
I've also made the parmaeters const reference types. This helps program stability since it means that the function cannot modify a and b.

Unexpected result by sqrt() in quadratic formula using <math.h>

This is the task i was given
Your task is to create a class named equation which will have the data members a, b and c which are the coefficients
of the quadratic equation. The class will have two more data members namely proot and nroot which stand for the
positive root and negative root of the equation. Suppose that variables a, b and c are integers. Where proot and nroot
are floats.
- Construct the class objects by using a nullary constructor.
- Then design a friend function which will determine the proot and nroot of the equation.
- Create another friend function which will display the values of proot and nroot.
I have a couple of questions
I tried to declare "a" as an integer and take its square root it was giving an error saying that "More than one instances of sqrt match the argument list". Same thing worked when i declared "a" as double and type-casted into integer. Why is is so?
the output should be
-1
-1.5
but my output is entirely different. What am i doing Wrong?
My professor told me that to make a function friend of a class we have to write its prototype in the class. Prototype does not include "&" but if i dont write it the program does not work
enter code here
#include <iostream>
#include <math.h>
using namespace std;
class Equation
{
friend void Roots (Equation & );
friend void Display (Equation &);
int a;
int b;
int c;
float proot;
float nroot;
public:
Equation ()
{
a=0;
b=0;
c=0;
proot=0;
nroot=0;
}
Equation (int _a, int _b, int _c)
{
a=_a;
b=_b;
c=_c;
}
};
void Roots (Equation &obj1)
{
double a;
int determinant;
a=(obj1.b^2)-(4*obj1.a * obj1.c);
if (a>-1)
determinant=int(sqrt(a));
else
{
cout<<"Determinant returns an imaginary number; solution not possible\n";
exit (0);
}
obj1.proot= (-obj1.b + determinant)/2*obj1.a;
obj1.nroot= (-obj1.b - determinant)/2*obj1.a;
}
void Display (Equation &obj1)
{
cout<<"Value of positive root : "<<obj1.proot<<endl;
cout<<"Value of negative root : "<<obj1.nroot<<endl;
}
void main ()
{
int a,b,c;
cout<<"Calculate Quadratic Equation"<<endl<<"Enter A : ";
cin>>a;
cout<<"Enter B : ";
cin>>b;
cout<<"Enter C ";
cin>>c;
Equation obj(a,b,c);
Display (obj);
Display (obj);
}
a=(obj1.b^2)-(4*obj1.a * obj1.c);
The ^ operator in C++ is a bitwise XOR, so obj1.b^2 part calculates the XOR of obj1.b and the bit pattern 000...10. That is definitely not what you want here.
The power function in C++ is pow, so you square that by doing pow(obj1.b, 2), also if you're working with C++ it would be better to include the header as cmath and not math.h.
EDIT: You also never call Roots() to calculate anything:
Equation obj(a,b,c);
Display (obj);
Here you construct your equation and immediately try to show its result, without first calling Roots(obj). That will at least calculate an answer but is still wrong because there seems to be a mistake in your calculation.
You also need parenthesis around 2 * obj1.a in your calculation. Try with and without them and see the difference!
Calculate Quadratic Equation
Enter A : 10
Enter B : 10
Enter C 2
Value of positive root : -0.276393
Value of negative root : -0.723607
And this is correct. Although you apparently expect the two roots to have different signs, that is not necessarily going to be the case.
Instead of
obj1.b^2
try
pow(obj1.b, 2)
^ is doing a XOR operation - probably not what you had in mind.
You also never seem to call your Roots function. You need something like:
Equation obj(a,b,c);
Roots(obj);
Display (obj);
You are getting big numbers returned, because when you call the Equation (int _a, int _b, int _c) constructor, proot and nroot are left uninitialized. You are then returning them at the end, because you never call the Roots function.
As an example of how to create useful friend functions:
#include <iostream>
#include <cmath>
class Equation
{
public:
Equation () : m_a(0), m_b(0), m_c(0), m_proot(0), m_nroot(0)
{
}
Equation (int a, int b, int c) : m_a(a), m_b(b), m_c(c), m_proot(0, false), m_nroot(0, false)
{
}
private:
// these would be better as floats or doubles, but your requirement appears to want them to be ints. You'll need to cast them when doing division operations.
int m_a;
int m_b;
int m_c;
// std::optional would be more useful, but it was removed from the last C++14 draft
std::pair<float, bool> m_proot;
std::pair<float, bool> m_nroot;
void Calculate()
{
// do your actual calculations here
// note that you will need to set the m_proot.second and m_nroot.second values to true if they are valid
// also note that ^ is not a power operation; you need to use std::pow for that
}
// this friend function is useful
friend std::ostream& operator<<(std::ostream&, const Equation&);
// this one is created just to meet the requirements of the assignment
friend void CalculateRoots(Equation&);
};
std::ostream& operator<<(std::ostream& os, const Equation& e)
{
std::cout << "Roots of (" << e.m_a << ")x^2 + (" << e.m_b << ")x + " << e.m_c << ": "
if (m_nroot.second || m_proot.second)
{
std::cout << "(";
if (m_nroot.second)
{
std::cout << m_nroot.first << ", ";
}
if (m_proot.second)
{
std::cout << m_proot.first;
}
std::cout << ")" << std::endl;
}
else
{
std::cout << "No real roots" << std::endl;
}
return os;
}
// must be friend function to call private member function Calculate
void CalculateRoots(Equation &obj1)
{
obj1.Calculate();
}
// does not need to be a friend function - using operator<< overload (which is a friend function itself)
void DisplayRoots(Equation &obj1)
{
std::cout << obj1;
}
int main ()
{
int a,b,c;
cout<<"Calculate Quadratic Equation"<<endl<<"Enter A : ";
cin>>a;
cout<<"Enter B : ";
cin>>b;
cout<<"Enter C ";
cin>>c;
Equation obj(a,b,c);
CalculateRoots(obj);
DisplayRoots(obj);
}
This gives you the required friend functions from the assignment's description while at least pushing you closer to a better design.
Ok guys so i changed the data type of variables from
int a;
int b;
int c;
to
float a;
float b;
float c;
because it was giving warning about conversions and data loss and also changed the statement where proot and nroot are calculated from
obj1.proot= (-obj1.b + determinant)/2*obj1.a;
obj1.nroot= (-obj1.b - determinant)/2*obj1.a;
to
obj1.proot= (-obj1.b + determinant)/(2*obj1.a);
obj1.nroot= (-obj1.b - determinant)/(2*obj1.a);
Now it is working as expected...Producing correct reusult! :)