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