Invalid cast from Complex* to double - c++

I have to return the distance between two complex numbers and the error I get is in the return line saying "Invalid cast from Complex* to double".
double Complex::distance(const Complex &a, const Complex &b)
{
Complex *number = new Complex();
number->modificaRe(a.real() - b.real());
number->modificaIm(a.imag() - b.imag());
return (double)number;
}
Could you please tell me what is it that I'm doing wrong?
Not to mention that the teacher gave us the definition of this function as "static double" but I was getting another error so I just removed "static".

The problem is that a double cannot carry both the real and imaginary parts of the Complex.
I believe that the distance between two complex numbers is the sqrt of the sum of the square of the differences.
So, you code should be...
double Complex::distance(const Complex &a, const Complex &b)
{
double number;
double r = a.real() - b.real();
double i = a.imag() - b.imag();
number = sqrt(r*r + i*i);
return number;
}
As H2CO3 points out it may be safter to use std::hypot...so
double Complex::distance(const Complex &a, const Complex &b)
{
return std::hypot(a.real() - b.real(), a.imag() - b.imag());
}

If I remember correctly the distance can be calculated using pythagorus - so creating the
Complex object in distance() is not necessary.
double Complex::distance(const Complex &a, const Complex &b)
{
double x = a.real() - b.real();
double y = a.imag() - b.imag();
return sqrt(x * x + y * y);
}

The easiest solution would be to use the standard library's std::comlpex class template. You can use subtraction and std::abs to get the "distance":
#include <complex>
#include <iostream>
template <typename T>
T complex_distance(const std::complex<T>& a, const std::complex<T>& b)
{
return std::abs(b-a);
}
int main()
{
std::complex<double> c1(-1,-1);
std::complex<double> c2(2,2);
std::cout << (c2-c1) << std::endl;
std::cout << complex_distance(c2,c1) << std::endl;
}

Casting from a pointer to a Complex to a double is not supported. It's not even clear why you're creating a pointer here rather than just allocating it on the stack.
For example:
double Complex::distance(const Complex &a, const Complex &b)
{
Complex number;
number.modificaRe(a.real() - b.real());
number.modificaIm(a.imag() - b.imag());
return (double)number;
}

Related

Subtle differences in output values (+/-) between float and doubles

This is a follow up from an older question found here: Chaining Function Calls and user Mooing Duck provided me with an answer that works through the use of Proxy Class and Proxy functions. I have managed to template this class and it appears to be working. I'm getting completely different results between float and double...
Here are the non templated versions of the classes and application for floats and doubles:
Just replace all floats with doubles within the classes, functions, and proxy functions... The main program won't change except for the arguments.
#include <cmath>
#include <exception>
#include <iostream>
#include <utility>
namespace pipes {
const double PI = 4 * atan(1);
struct vec2 {
float x;
float y;
};
std::ostream& operator<<(std::ostream& out, vec2 v2) {
return out << v2.x << ',' << v2.y;
}
vec2 translate(vec2 in, float a) {
return vec2{ in.x + a, in.y + a };
}
vec2 rotate(vec2 in, float a) {
// convert a in degrees to radians:
a *= (float)(PI / 180.0);
return vec2{ in.x*cos(a) - in.y*sin(a),
in.x*sin(a) + in.y*cos(a) };
}
vec2 scale(vec2 in, float a) {
return vec2{ in.x*a, in.y*a };
}
// proxy class
template<class rhst, vec2(*f)(vec2, rhst)>
class vec2_op1 {
std::decay_t<rhst> rhs; // store the parameter until the call
public:
vec2_op1(rhst rhs_) : rhs(std::forward<rhst>(rhs_)) {}
vec2 operator()(vec2 lhs) { return f(lhs, std::forward<rhst>(rhs)); }
};
// proxy methods
vec2_op1<float, translate> translate(float a) { return { a }; }
vec2_op1<float, rotate> rotate(float a) { return { a }; }
vec2_op1<float, scale> scale(float a) { return { a }; }
// lhs is the object, rhs is the operation on the object
template<class rhst, vec2(*f)(vec2, rhst)>
vec2& operator|(vec2& lhs, vec2_op1<rhst, f>&& op) { return lhs = op(lhs); }
} // namespace pipes
int main() {
try {
pipes::vec2 a{ 1.0, 0.0 };
pipes::vec2 b = (a | pipes::rotate(90.0));
std::cout << b << '\n';
} catch (const std::exception& e) {
std::cerr << e.what() << "\n\n";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
Output for float:
-4.37114e-08,1
Output for double:
6.12323e-17,1
Here is the templated version...
#include <cmath>
#include <exception>
#include <iostream>
#include <utility>
namespace pipes {
const double PI = 4 * atan(1);
template<typename Ty>
struct vec2_t {
Ty x;
Ty y;
};
template<typename Ty>
std::ostream& operator<<(std::ostream& out, vec2_t<Ty> v2) {
return out << v2.x << ',' << v2.y;
}
template<typename Ty>
vec2_t<Ty> translate(vec2_t<Ty> in, Ty a) {
return vec2_t<Ty>{ in.x + a, in.y + a };
}
template<typename Ty>
vec2_t<Ty> rotate(vec2_t<Ty> in, Ty a) {
// convert a in degrees to radians:
a *= (Ty)(PI / 180.0);
return vec2_t<Ty>{ in.x*cos(a) - in.y*sin(a),
in.x*sin(a) + in.y*cos(a) };
}
template<typename Ty>
vec2_t<Ty> scale(vec2_t<Ty> in, Ty a) {
return vec2_t<Ty>{ in.x*a, in.y*a };
}
// proxy class
template<class rhst, typename Ty, vec2_t<Ty>(*f)(vec2_t<Ty>, rhst)>
class vec2_op1 {
std::decay_t<rhst> rhs; // store the parameter until the call
public:
vec2_op1(rhst rhs_) : rhs(std::forward<rhst>(rhs_)) {}
vec2_t<Ty> operator()(vec2_t<Ty> lhs) { return f(lhs, std::forward<rhst>(rhs)); }
};
// proxy methods
template<typename Ty>
vec2_op1<Ty, Ty, translate<Ty>> translate(Ty a) { return { a }; }
template<typename Ty>
vec2_op1<Ty, Ty, rotate<Ty>> rotate(Ty a) { return { a }; }
template<typename Ty>
vec2_op1<Ty, Ty, scale<Ty>> scale(Ty a) { return { a }; }
// overloaded | operator for chaining function calls to vec2_t objects
// lhs is the object, rhs is the operation on the object
template<class rhst, typename Ty, vec2_t<Ty>(*f)(vec2_t<Ty>, rhst)>
vec2_t<Ty>& operator|(vec2_t<Ty>& lhs, vec2_op1<rhst, Ty, f>&& op) { return lhs = op(lhs); }
} // namespace pipes
// for double just instantiate with double...
int main() {
try {
pipes::vec2_t<float> a{ 1.0f, 0.0f };
pipes::vec2_t<float> b = (a | pipes::rotate(90.0f));
std::cout << b << '\n';
} catch (const std::exception& e) {
std::cerr << e.what() << "\n\n";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
The output for floats:
-4.37114e-08,1
The output for doubles:
6.12323e-17,1
This goes to show that the conversion of my class to a class template appears to be working. I understand that there may be a bit of precision lost due to conversion from double to float or widening from float to double when casting, however, I can't seem to wrap my mind around why there is such a difference in output values from one to the other...
The rotation of the point or vector {1,0} at 90 degrees or PI/2 radians should be {0,1}. I understand how floating-point arithmetic works and that the generated output for the x values is relatively close to 0 so they should be considered 0 for all tense and purposes and I can include the use an epsilon checking function to test if it is close enough to 0 to set it directly to 0 which is not an issue...
What intrigues my curiosity is why is it -4.3...e-8 for float and +6.1...e-17 for double? In the float case, I'm getting negative values, and for the double case, I'm getting positive values. In both cases yes they are extremely small and close to 0 which is fine, but opposite signs, that has me scratching my head?
I'm seeking clarity to get a better insight as to why these values are being generated the way they are... Is it coming from the type-conversion or is it due to the trig function that is being used? Or a combination of both? Just trying to pinpoint where the divergence of signs is coming from...
I need to be aware of what is causing this subtle difference as it will pertain to my usage of this class and its generated outputs when precision is preferred over good enough estimations.
Edit
When working with the instantiation of these function templates, specifically for the rotate function and I started to test <int> type for my vector objects... I started to get some compiler errors... The translate and scale functions were fine, I only had an issue with the rotate function due to similar reasons loss of data, narrowing and widening conversions, etc...
I had to change my rotate function's implemenation to this:
template<typename Ty>
vec2_t<Ty> rotate(vec2_t<Ty> in, Ty a) {
// convert a in degrees to radians:
auto angle = (double)(a * (PI / 180.0));
return vec2_t<Ty>{ static_cast<Ty>( in.x*cos(angle) - in.y*sin(angle) ),
static_cast<Ty>( in.x*sin(angle) + in.y*cos(angle) )
};
}
Here I'm forcing the angle to always be a double regardless of the type Ty. The rotate function still expects the same type for its argument as the type of the vec2_t object that is being instantiated. The issue was with the initialization of the vec2_t object that was being created and returned from the calculations. I had to explicitly static_cast the x and y coordinates to Ty. Now when I try the same program above for vec2_t<int> passing in a rotation value of 90 I am getting exactly 0,1 for my output.
Another interesting fact by forcing the angle to always be double and always casting the calculated values back to Ty, when I instantiate my vec2_t as either a double or float I'm always getting the positive 6.123...e-17 result back for both cases... This should also allow me to simplify the design of the is_zero() function to test if these values are close enough to 0 to set them explicitly to 0.
TL;DR: Small numbers are close to zero whatever their sign. The numbers you got are "almost zero" given the circumstances.
I'd call this "sign obsession". Two very small numbers are similar even if their signs differ. Here you're looking at numbers at the edge of accuracy of the computations you performed. They are both equally "small", given their types. Other answer(s) give hints about where exactly is the clbuttic mistake :)
Your problem is in the line:
a *= (Ty)(PI / 180.0);
For the float case, this evaluates to 1.570796371
For the double case, this evaluates to 1.570796327

Passing function of multiple arguments that contains class to other function

I'm trying to pass function of multiple arguments to other function. I know how to pass a function of single argument function to other function as it was described in C++ primer plus book.
However, I get an error when I'm trying to pass multiple arguments with class(poly_3d) to NR_method function.
#include <iostream>
#define log(x) std::cout<<x<<std::endl;
class constants {
public:
double A;
double B;
double C;
};
double poly_3d(double x, constants cst);
double NR_method(double a, double(*poly_3d)(double));
int main() {
constants cst;
cst.A = 2;
cst.B = -8;
cst.C = 10;
NR_method(3.2, poly_3d);
system("PAUSE");
return 0;
}
double poly_3d(double x, constants cst) {
double y = 3 * cst.A*x*x + 2 * cst.B*x + cst.C;
return y;
}
double NR_method(double a, double (*poly_3d)(double)) {
double c = (*poly_3d)(a);
return c;
}
So the error I'm getting is from NR_method(3.2, poly_3d) in main function. I know that if poly_3d was single arg, this would work.
If this is a horrible way to write codes, then any directions towards learning C++ more effectively for newbies would be much appreciated! Thanks
Take a look at the following code. We're using a template to make things look nicer.
#include <iostream>
#define log(x) std::cout<<x<<std::endl;
class constants {
public:
double A;
double B;
double C;
};
/// Note that we take a ref now, no need to copy cst.
double poly_3d(double x, constants & cst)
{
double y = 3 * cst.A*x*x + 2 * cst.B*x + cst.C;
return y;
}
/// Note that we take a ref now, no need to copy cst.
template <class F>
double NR_method(double a, constants & cst, F func)
{
return func(a, cst);
}
int main() {
constants cst;
cst.A = 2;
cst.B = -8;
cst.C = 10;
NR_method(3.2, cst, &poly_3d);
system("PAUSE");
return 0;
}
You are declaring the function poly_3d with 2 arguments but passing only one. I made a few changes on the code for you
#include <iostream>
#define log(x) std::cout<<x<<std::endl;
class constants {
public:
double A;
double B;
double C;
};
double poly_3d(double x, constants cst);
double NR_method(double a, constants cst, double(*poly_3d)(double, constants));
int main() {
constants cst;
cst.A = 2;
cst.B = -8;
cst.C = 10;
printf("%f", NR_method(3.2, cst, poly_3d));
system("PAUSE");
return 0;
}
double poly_3d(double x, constants cst) {
double y = 3 * cst.A*x*x + 2 * cst.B*x + cst.C;
return y;
}
double NR_method(double a, constants cst, double (*poly)(double, constants)) {
return (*poly)(a, cst);
}
Let's start by simplifying your code. (A minimal example removes distractions, allowing you to better focus on the actual issue.) It looks like you started to do this, but it can be taken further. After removing some stuff that is not needed to reproduce the compile error:
class constants {};
double poly_3d(double x, constants cst);
double NR_method(double a, double(*poly_3d)(double));
int main() {
NR_method(3.2, poly_3d);
}
double poly_3d(double x, constants /*cst*/) {
return 3 * x;
}
double NR_method(double a, double (*poly_3d)(double)) {
return (*poly_3d)(a);
}
Now let's look at the error message:
error: invalid conversion from 'double (*)(double, constants)' to 'double (*)(double)'
This comes with an indication that the conversion is from poly_3d to the second argument of NR_method. If you look at those things, yes, that is the conversion you requested. The argument list for poly_3d is (double, constant), while the declared argument list for the second argument is just (double). There is a mismatch, which makes the conversion invalid. It's not all that different from the single-parameter case: the signatures must match. You can solve this by changing the argument's signature to math that of poly_3d.
Now, if you just make the signatures match, there is another problem in that NR_method does not have a constants value available. That is probably a logical error for you to work out. For a quick workaround to show the elimination of the compiler error, I'll add a local variable.
class constants {
};
double poly_3d(double x, constants cst);
double NR_method(double a, double(*poly_3d)(double, constants)); // <-- Desired signature
int main() {
NR_method(3.2, poly_3d);
}
double poly_3d(double x, constants /*cst*/) {
return 3.0 * x;
}
double NR_method(double a, double (*poly_3d)(double, constants)) {
constants cst; // <-- Allows this to compile, but probably not what you want.
return (*poly_3d)(a, cst); // <-- Needed a second parameter here.
}
There are ways to make this work nicer (for example, a std::function may be more convenient than a function pointer), but explaining those would fall outside the scope of this question, especially since some decisions would depend on the bigger picture.

Overloading operator+ in c++

I have a little problem with one of my task for exercise for exam. This is a text:
Class MyFloat have a private variable float num. You have to write methods which will enable next lines of code:
MyFloat x = 3.5;
MyFloat y = x + 3.2
float z = 3.4 + y
And I write this code:
#include <iostream>
#include <Windows.h>
using namespace std;
class MyFloat
{
float num;
public:
MyFloat(float n)
{
num = n;
}
MyFloat operator+(MyFloat x)
{
float result;
result = x.num + this->num;
return result;
}
};
int main()
{
MyFloat x = 3.75;
MyFloat y = x + 3.2;
float z = 3.4 + y;
system("PAUSE");
}
I get error in this line:
float z = 3.4 + y;
It says:
error C2677: binary '+' : no global operator found which takes type 'MyFloat' (or there is no acceptable conversion)
What should I do? How to solve this problem???
Implement operator+ as non-member friend function with 2 arguments MyFloat operator+(MyFloat x, MyFloat y).
Why doesn't it work in the current version? Because member operator functions are called on the objects on the left side of the operator. In your case on the left side you have integer literal which is not an object so lacks MyFloat operator+(MyFloat x) member function.
Non-member variants of operators are symmetrical and do not require the left side being an object. Symmetricity is important because as you see in your example operator+ is not symmetrical as we are used to think in math
Edit: But this is still not enough as noted by Cassio Neri in comments. Why? See his answer for the explanation but in short: you have ambiguity problems. You can use either his solution or this one if you do manual casting like this: float z = 3.4f + static_cast<float>(y); which is quite ugly. You can use another cast: float z = MyFloat(3.4f) + y if you provide MyFloat::operator float conversion.
Another solution to solve the same ambiguity problem: In C++11 you could use your own suffix literal (similar to f prefix for built-in floats, for example 3.4_f; (underscore means that this suffix literal is user-defined). Sample implementation (given that you implement operators for casting from MyFloat to float and backwards:
MyFloat operator "" _f(long double val) {
return MyFloat(static_cast<float>(val)); }
int main() {
MyFloat x = 3.75;
MyFloat y = x + 3.2;
float z = 3.4_f + y;
}
This can be a solution:
class MyFloat
{
float num;
public:
MyFloat(float n)
{
num = n;
}
operator float() const {
return num;
}
};
int main()
{
MyFloat x = 3.75;
MyFloat y = x + 3.2f;
float z = 3.4f + y;
}
Initially, I also though about making MyFloat operator+(MyFloat, MyFloat) a non-member friend function but it still doesn't make the line
float z = 3.4 + y;
to compile. The reason is that 3.4 + y will be of type MyFloat and therefore you can't assign it to float z unless you provide a converting operator from MyFloat to float. Buth then, 3.4f + y becomes ambiguous (at least for VS 2010) because it can either call MyFloat operator+(MyFloat, MyFloat) or it can convert y to float and use the built-in operator + for floats.
You only have MyFloat + float operation, and you need to define float + MyFloat operation too. They are not the same.
Add this to your public functions:
friend float operator+ (const float& lhs, const MyFloat& rhs);
And this outside the class:
float operator+ (const float& lhs, const MyFloat& rhs) {
return lhs + rhs.num;
}
Note: Edited as per comment by CassioNeri.
While you can proceed with the answer where you define the "cast to float" approach, I believe it is better for your own sake that you start making use of your public API to implement additional behavior.
In general, a simple "casting" will not do the trick (for example, what happens if MyFloat were MyMatrix?).
The approach below is certainly more verbose, but it stresses that you should "eat your own food", meaning that you should try to implement additional behavior based on your own public interface, rather than a bunch of obscure implicit casts, or friend functions. If you use your own API: You will understand its limitations, and may potentially save recompilation of the main class if you make modifications.
Also, suppose that you wanted to count the accesses to your class (or otherwise control access to the underlying value): using the casting operator you would need to duplicate the code in operator float() and in float value().
So, here is my humble suggestion which appears longer but, to my taste, better reflects OO design principles.
#include<iostream>
class MyFloat {
public:
MyFloat(float value):
m_value(value) { }
float value() const {
return m_value;
}
private:
float m_value;
};
// Eat your own food: implement functions using your public interface
// until proven need to do otherwise. This will help you assess the
// usability of your API.
float operator+(const MyFloat& lhs, const MyFloat& rhs) { return lhs.value() + rhs.value(); }
float operator+(const MyFloat& lhs, float rhs) { return lhs.value() + rhs; }
float operator+(float lhs, const MyFloat& rhs) { return lhs + rhs.value(); }
// See, now I can define another operator without need to recompile my
// class (this could have been placed in another file)
std::ostream& operator<<(std::ostream& os, const MyFloat& mf) {
os<<"MyFloat("<<mf.value()<<")";
return os;
}
int main() {
MyFloat x = 3.5; // would not work if I had declared the constructor as "explicit"
MyFloat y = x + 3.2;
MyFloat z = 3.4 + y;
std::cout<<x<<", "<<y<<", "<<z<<std::endl;
}
Output (compiled with g++ example.cpp -Wall -Wextra):
MyFloat(3.5), MyFloat(6.7), MyFloat(10.1)

How to evaluate a function directly?

Title may not make any sense but I dont really know how to explain this.
I have a class called polynomial and lets say I defined a polynome called p1 which is 2x+4. What I want to do is calculate p1(5) directly. I dont want anything like double calculate (polynomial) etc I want to be able to calculate my polynom with p1(x).
I hope my question is clear
Overload the function-call operator:
struct polynomial
{
double a, b;
polynomial(double m, double n) : a(m), b(n) { } // represents "a * x + b"
double operator()(double x) const
{
return a * x + b;
}
};
Usage:
polynomial p(2.5, 3.8);
double val = p(1.0);
By overloading operator() you can "call" an object just like you would call a function:
struct polynomial {
int operator()(int x)
{
/* calculate */
}
};
int main()
{
polynomial p;
int x = p(5);
}

How to calculate the sum of a vector without using loop or std::accumulate()?

I'm trying to implement an Euclidean vector for my programming assignment. I need to overload operator* to provide dot product calculation for two vectors with arbitrary same dimension.
As 3D vector for example:
Vector<3> v1, v2; //two 3D vectors.
double dotProduct = v1 * v2;
The value of dotProduct should be v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]
So, my problem is how to get this value without using any explicit loop and std::accumulate() operation in numeric.h header file? Because those are forbidden in this assignment.
P.S. I may use functor(self defined) together with STL algorithm.
If you really want to avoid explicit loops and algorithms in general (not just std::accumulate), you could use std::valarrays instead:
std::valarray<double> a;
std::valarray<double> b;
// code to put data in a and b goes here
double dotProduct = (a * b).sum();
I've used double as the type here, but you can (of course) use whatever type makes sense for the data/situation you're dealing with.
You can use std::inner_product, see http://en.cppreference.com/w/cpp/algorithm/inner_product
double dotProduct = std::inner_product(v1.begin(), v1.end(), v2.begin());
If you can't use explicit loops, perhaps your teacher is asking you to use recursion.
template<int N>
int VectorSum(const Vector<N>& v1, const Vector<N>& v2, int m) {
if(m) return v1[m]*v2[m] + VectorSum(v1, v2, m-1);
return v1[0]*v2[0];
}
template<int N>
int operator+(const Vector<N>& v1, const Vector<N>& v2) {
return VectorSum(v1, v2, N-1);
}
I happened to read a text about it, so I copy it for you. may be it's introduced in the book :C++ Templates: The Complete Guide.
#include <iostream>
template<int DIM,typename T>
struct DotProduct {
static T execute(const T v1[],const T v2[]);
};
template<int DIM,typename T>
T DotProduct<DIM,T>::execute(const T v1[],const T v2[]) {
return v1[0]*v2[0] + DotProduct<DIM-1,T>::execute(v1+1,v2+1);
};
template<typename T>
struct DotProduct<1,T> {
static T execute(const T v1[],const T v2[]);
};
template<typename T>
T DotProduct<1,T>::execute(const T v1[],const T v2[]) {
return v1[0]*v2[0];
};
int main()
{
int v1[] = {1,2,3};
int v2[] = {4,5,6};
int r2 = DotProduct<3,int>::execute(v1,v2);
std::cout << r2 << std::endl;
return 0;
}