Квадратный корень комплексных чисел в python

Я столкнулся с каким-то запутанным поведением с квадратными корнями комплексных чисел в python. Запуск этого кода:

from cmath import sqrt
a = 0.2
b = 0.2 + 0j
print(sqrt(a / (a - 1)))
print(sqrt(b / (b - 1)))

дает выход

0.5j
-0.5j

Аналогичная ситуация с

print(sqrt(-1 * b))
print(sqrt(-b))

Кажется, эти пары утверждений должны дать тот же ответ?

Ответ 1

Оба ответа (+0.5j и -0.5j) верны, так как они комплексные сопряжения - то есть действительная часть идентична, а мнимая часть - с перевернутым знаком.

Глядя на код, делает поведение ясным - мнимая часть результата всегда имеет тот же знак, что и мнимая часть ввода, как видно из строк 790 и 793:

r.imag = copysign(d, z.imag);

Так как a/(a-1) есть 0.25, что неявно 0.25+0j, вы получаете положительный результат; b/(b-1) создает 0.25-0j (по какой-то причине, не уверен, почему это не приводит к 0.25+0j tbh), поэтому ваш результат аналогично отрицателен.

EDIT: Этот вопрос содержит полезное обсуждение по той же проблеме.

Ответ 2

Я могу ответить, почему это происходит, но не почему было выбрано поведение.

a/(a - 1)

оценивается до 0,2/-0,8, что составляет -0,25, которое преобразуется в комплексное число на cmath.sqrt, а

b/(b - 1)

оценивает (0.2 + 0j)/(- 0.8 + 0j), который равен (-0.25-0j), который преобразуется в комплексное число с отрицательной комплексной составляющей.

Для более простого примера,

cmath.sqrt(0j) == 0j
cmath.sqrt(-0j) == -0j