C++ Logo

std-discussion

Advanced search

Re: Problems with pow(std::complex<T>, double)

From: Hyman Rosen <hyrosen_at_[hidden]>
Date: Wed, 3 Mar 2021 17:04:45 -0500
On Wed, Mar 3, 2021 at 9:05 AM Bell, Ian H. (Fed) via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> std::cout << pow(std::complex<double>(-0.1, 1e-100), 2.0) << std::endl;
>
> gives
>
> (0.01,-2.44929e-18)
>
Here are the calculations being carried out:

log(a + bi) = log(a*a + b*b) / 2 + i * atan2(b, a)
exp(a + bi) = exp(a) * cos(b) + i * exp(a) * sin(b)

In your case, you have x = -.1 + 1e-100i,
so l = log(x) = log(.1) + i * atan2(1e-100, -.1) = log(.1) + i * numbers::pi

Then exp(2*l) = exp(2*log(.1) + i * 2 * numbers::pi)
              = .01 * (cos(2 * numbers::pi) + i * sin(2 * numbers::pi))
              = .01 - i * 2.4492935982947064e-18
Basically, atan2(1e-100, -.1) just gives you numbers::pi, and then
sin(2 * numbers::pi) isn't 0 because numbers::pi isn't exactly π.
Doubles don't have enough precision to be able to deal with complex
logarithms and trigonometry at this scale.

Received on 2021-03-03 16:05:03