4

For some reason the string representation of negative imaginary numbers in Python is different for equal values:

>>> str(-3j)
'(-0-3j)'
>>> str(0-3j)
'-3j'

Moreover, if I try to get the string representation of -0-3j, I get:

>>> str(-0-3j)
'-3j'

Which seems like an inconsistency.

The problem is that I use the string representation of complex scalar tensors to compute the hash of some operators, and because of this inconsistency I get different hashes for equal operators.

Is there any way to convert '(-0-3j)' to '-3j'?

Edit:

Mechanic Pig pointed out that:

>>> str(-0.-3j)
'(-0-3j)'
amitjans
  • 83
  • 1
  • 7
  • If you add the decimal point `-0.-3j`, its result will be `'-0-3j'`, because integers do not distinguish between positive and negative zeros, but floating-point numbers do. – Mechanic Pig Sep 13 '22 at 09:02

1 Answers1

2

This issue is filed as a bug and stimulated appearance of PEP-0682 - Format Specifier for Signed Zero and originates from Floating-point arithmetic limitations.

Once the bug is resolved -0 will not scare unnecessarily any more. But until then...

You can adapt the snippet from this answer:

def real_norm(no):
    return no if no != 0 else abs(no)
    
def imag_norm(ino):
    return complex(real_norm(ino.real), real_norm(ino.imag))

test_cases = [-0-3j, 0-3j, -0-0j, 0-0j, -0+0j]
for tc in test_cases:
    tn = imag_norm(tc)
    print(f"{tc} -> {tn}")
sophros
  • 14,672
  • 11
  • 46
  • 75