Bogus parsing/eval of complex literals

 ̄綄美尐妖づ 提交于 2020-01-06 03:06:08

问题


When evaluating complex numbers, python likes to fiddle the signs.

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

Why?

nb: I noticed it when reading this question.


回答1:


The issue here is that Python doesn't parse complex numbers such as (-0-0j) as literals, they are actually parsed as an expression:

>>> 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)))])'

So, this is not a complex literal but a reflected subtraction of a complex and an integer.

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

The int part is coerced to having a 0j complex component, and then we lose the expected 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 dictates.

This is arguably a parser issue, because the sign of the zero can influence the solutions of equations. However, the issue has been 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 built-in:

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


来源:https://stackoverflow.com/questions/36603561/bogus-parsing-eval-of-complex-literals

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!