复杂文字的伪造 parsing/eval

Bogus parsing/eval of complex literals

计算复数时,python喜欢fiddle符号。

>>> -0j
(-0-0j)
>>> (-0-0j)
0j

为什么?

nb: 我在看问题的时候注意到了。

这里的问题是 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 复杂组件,然后我们失去了预期的 signed zero from the result because of the subtraction of the complex components. The result of 0j - 0j should have positive sign, as IEEE 754-2008 指令。

这可以说是解析器问题,因为零的符号会影响方程的解。但是,问题已 repeatedly raised and closed on the python tracker as 'not a bug', so it doesn't look like that behaviour will be going away any time soon. The reliable way to initialize complex numbers when you care about signed zeros is by calling the complex 内置:

>>> 0-0j
0j
>>> 0+0j
0j
>>> complex(0., -0.)
-0j
>>> complex(0., +0.)
0j