伪造解析/评估复杂的文字

时间:2016-04-13 15:50:17

标签: python parsing ieee-754 complex-numbers

在评估复数时,python喜欢摆弄符号。

这是Python 3.5.0(但在python 2中存在类似的奇怪问题)

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

为什么呢?

nb:我在阅读this问题时注意到了这一点。

1 个答案:

答案 0 :(得分:4)

这里的问题是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)))])'

所以,这不是一个复杂的文字,而是int和complex的减法。

>>> -0-0j
0j
>>> (0j).__rsub__((0).__neg__())
0j

int部分被视为具有0j复杂组件,然后由于复数组件的减法,我们从结果中丢失了预期的signed zero0j - 0j的结果应该是正号,正如IEEE 754-2008所指示的那样。

这可以说是一个解析器问题,因为零的符号可以影响方程的解。但是,python跟踪器上的repeatedly raisedclosed问题是“不是错误”,因此看起来这种行为不会很快消失。初始化复数的可靠方法是调用内置的complex

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