Reputation: 2060
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
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
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