The following code fails to compile
#include <iostream>
#include <cmath>
#include <complex>
using namespace std;
int main(void)
{
const double b=3;
complex <double> i(0, 1), comp;
comp = b*i;
comp = 3*i;
return 0;
}
with error: no match for ‘operator*’ in ‘3 * i’ What is wrong here, why cannot I multiply with immediate constants? b*i works.
To multiply two complex numbers a + ib and c + id , we perform (ac - bd) + i (ad+bc) . For example: multiplication of 1+2i and 2+1i will be 0+5i.
(x + yi) u = xu + yu i. In other words, you just multiply both parts of the complex number by the real number. For example, 2 times 3 + i is just 6 + 2i. Geometrically, when you double a complex number, just double the distance from the origin, 0.
In the first line:
comp = b*i;
The compiler calls:
template<class T> complex<T> operator*(const T& val, const complex<T>& rhs);
Which is instanced as:
template<> complex<double> operator*(const double& val, const complex<double>& rhs);
In the second case, there is no appropriate template int
, so the instancing fails:
comp = 3.0 * i; // no operator*(int, complex<double>)
the std::complex
class is a little bit stupid... define these to allow automatic promotions:
// Trick to allow type promotion below
template <typename T>
struct identity_t { typedef T type; };
/// Make working with std::complex<> nubmers suck less... allow promotion.
#define COMPLEX_OPS(OP) \
template <typename _Tp> \
std::complex<_Tp> \
operator OP(std::complex<_Tp> lhs, const typename identity_t<_Tp>::type & rhs) \
{ \
return lhs OP rhs; \
} \
template <typename _Tp> \
std::complex<_Tp> \
operator OP(const typename identity_t<_Tp>::type & lhs, const std::complex<_Tp> & rhs) \
{ \
return lhs OP rhs; \
}
COMPLEX_OPS(+)
COMPLEX_OPS(-)
COMPLEX_OPS(*)
COMPLEX_OPS(/)
#undef COMPLEX_OPS
See http://www.cplusplus.com/reference/std/complex/complex/operators/ for an overview of the complex operators.
You will notice that the operator* is a template and will use the template parameter of the complex class to generate that code. The number literal you use to invoke operator* is of type int. Use comp = 3. * i;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With