KaliMa
KaliMa

Reputation: 2060

C++ complex number multiplication

If I have (1+i)^2, the answer should be 2i

But if I do

std::complex<double> i = sqrt(1), one = 1;
cout << pow(one+i,2) << endl;

It outputs (4,0)

Upvotes: 1

Views: 4476

Answers (2)

SleuthEye
SleuthEye

Reputation: 14577

you are initializing i to sqrt(1) whereas you probably thought about sqrt(-1). As such it would be evaluated as a double expression (after -1 is converted to double as the closest matching sqrt, see Mike's comment for complete sequence), which according to cplusplus.com generates a domain error for negative arguments.

Instead you can initialize i as:

std::complex<double> i(0,1);

Alternatively you could use a complex number as argument to sqrt as described in this answer, or as Potatoswatter indicated in comments you could use 1.i with C++14 (should you have a compiler & standard library that supports user-defined literals for standard library types, part 2).

Upvotes: 4

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145429

The math.h header in C++ provides the following overloads of sqrt:

auto sqrt( float arg ) -> float;
auto sqrt( double arg ) -> double;
auto sqrt( long double arg ) -> long double;
auto sqrt( Integral arg ) -> double;    // C++11 and later

where Integral denotes any integral type (this is a set of overloads or a function template).

The <complex> header additionally defines this overload:

template< class T >
auto sqrt( complex<T> const& x ) -> complex<T>;

There's also an overload for valarray, but it's not relevant here.

When you use -1 as actual argument, like

sqrt( -1 )

the direct match of the argument type, the overload with Integral argument, is best fit, and that overload returns a double.

There is no way to represent the mathematical i as a double value. So the value that you get is an implementation-defined value (if your C++ implementation's double type supports NaN, Not a Number, it can be a NaN); “whether the integer expression errno acquires the value EDOM is implementation-defined” according to C99 §7.12.1/2. To avoid that you can make sure that the -1 is converted to an argument of type complex<double>, say:

sqrt( complex<double>( -1 ) )

With the compilers I tried this yields the same result as writing

complex<double>( 0, 1 )

which represents the mathematical i, the square root of minus 1.

Upvotes: 1

Related Questions