Search code examples
pythonpython-3.xpython-internals

Why/how do -1j and 0-1j become different strings?


Why and how are -1j and 0 - 1j turned into different strings?

>>> a = -1j
>>> b = 0 - 1j
>>> a
(-0-1j)
>>> b
-1j

They're the same value of the same type:

>>> a == b
True
>>> type(a), type(b), type(a) is type(b)
(<class 'complex'>, <class 'complex'>, True)

But both str and repr turn them into different strings:

>>> str(a), str(b)
('(-0-1j)', '-1j')
>>> repr(a), repr(b)
('(-0-1j)', '-1j')

Why and how does that happen?

Note: This is in Python 3.6.4. In Python 2.7.14 they're both turned into '-1j'.


Solution

  • a has a real component of -0.0, while b has a real component of 0.0. The 0.0 is omitted from the string representation.

    -1j is treated as -(1j), where 1j has a real component of 0.0. That real component gets negated.

    In 0 - 1j, the real components of both sides are 0, and the subtraction produces a real component of 0.

    On Python 2, I think -1j probably hits the same special case used to make -2147483648 or -9223372036854775808 (platform-dependent) evaluate to an int instead of a long. The special-case handling seems to result in a real component of 0.0.