I am never going to complain about Python again

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Oct 10 22:08:52 EDT 2013


On Thu, 10 Oct 2013 09:09:42 -0400, Roy Smith wrote:

> BTW, here's a Python equality oddity:
> 
>>>> r = 0.0
>>>> c = 0 + 0j
>>>> r == c
> True

Mathematically, this is only to be expected.


>>>> int(r) == int(c)
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: can't convert complex to int


This is also to be expected. What should int(a+bj) return?

★  int(a) + int(b)j

★  int(a)

★  int(b)

★  int(abs(a + bj))


It's quite ambiguous, there is no obvious mapping from complex to 
integers, and so should raise an exception.


 
> If x == y, then f(x) should also equal f(y).

Not necessarily. If x and y are different types, which they are here, 
then function f may be defined on one type but not the other. Which is 
exactly the case with int() on floats and complexes.


> More specifically, if x == y,
> and x is in the domain of f(), then y should also be in the domain of
> f().

Incorrect. By definition, complex numbers are in the Complex domain, not 
the Real domain.

Your mistake here seems to be that you're assuming that if two numbers 
are equal, they must be in the same domain, but that's not the case. 
(Perhaps you think that 0.0 == 0+0j should return False?) It's certainly 
not the case when it comes to types in Python, and it's not even the case 
in mathematics. Given:

x ∈ ℝ, x = 2  (reals)
y ∈ ℕ, y = 2  (natural numbers)

we have x = y, but since 1/y is undefined (there is no Natural number 
1/2), 1/x != 1/y.

Now, arguably in this case we could implicitly promote y to the reals 
before performing the division. I would consider that acceptable, since 
there is only one way to do the promotion: natural 2 -> real 2. But going 
the other way certainly isn't: demoting real x to the naturals is 
ambiguous, and even if it weren't, then declaring that 1/x isn't defined 
would make the whole exercise pointless.

Bringing this back to the initial example of int(0.0) == int(0+0j), to 
have this work the way you want would require demoting the complex number 
to the reals, and that is ambiguous. There are three distinct ways to do 
this: take the real part, the imaginary part, or the absolute value. That 
makes the operation "demote to real" ambiguous, the mere fact that all 
three operations would happen to give the same result for this particular 
number is irrelevant.


-- 
Steven



More information about the Python-list mailing list