При оценке комплексных чисел python любит возиться со знаками.
>>> -0j
(-0-0j)
>>> (-0-0j)
0j
Почему?
примечание: я заметил это, читая этот вопрос.
При оценке комплексных чисел python любит возиться со знаками.
>>> -0j
(-0-0j)
>>> (-0-0j)
0j
Почему?
примечание: я заметил это, читая этот вопрос.
Проблема здесь в том, что Python не анализирует комплексные числа, такие как (-0-0j)
, как литералы, они фактически анализируются как выражение:
>>> import ast
>>> ast.dump(ast.parse('(-0-0j)'))
'Module(body=[Expr(value=BinOp(left=UnaryOp(op=USub(), operand=Num(n=0)), op=Sub(), right=Num(n=0j)))])'
Таким образом, это не сложный литерал, а отраженное вычитание сложного и целого числа.
>>> -0-0j
0j
>>> (0j).__rsub__((0).__neg__())
0j
Часть int принудительно содержит сложный компонент 0j, после чего мы теряем ожидаемый ноль со знаком из результата из-за вычитания сложных компонентов. Результат 0j - 0j
должен иметь положительный знак, как IEEE 754-2008 диктует.
Возможно, это проблема синтаксического анализатора, потому что знак нуля может влиять на решения уравнений. Однако эта проблема неоднократно поднят и закрыт в трекере Python как ' не ошибка», так что не похоже, что это поведение исчезнет в ближайшее время. Надежный способ инициализировать комплексные числа, когда вам нужны нули со знаком, — это вызвать complex
встроенный:
>>> 0-0j
0j
>>> 0+0j
0j
>>> complex(0., -0.)
-0j
>>> complex(0., +0.)
0j