[Python-Dev] RE: [Python-checkins] python/dist/src/Objects complexobject.c,2.57,2.58

Tim Peters tim.one@comcast.net
Mon, 15 Apr 2002 17:25:38 -0400


[Guido, on deprecating % for complex]
> ...
> However, I'm wondering what to do after we unify all numeric types
> (*if* we ever decide to do that, which isn't clear).  At that point,
> should these operators be allowed as long as the imaginary part is
> zero?

Not if you ask me.  Because two mathematically equivalent expressions can
yield different results when evaluated via computer fp arithmetic, it's
impossible to guess whether a computed complex result "really" has a
non-zero imaginary part (indeed, under the constructive reals, answering
that question is equivalent to solving the halting problem -- it's not just
the finitude of fp arithmetic that's to blame for the uncertainty, and the
uncertainty runs deep).

In practical terms, this means the imaginary part of a given complex
expression can "round to 0", or not, depending on accidents of
implementation, evaluation order, platform library implementation, and fp
hardware.  If the language can't define when a complex expression is safe to
use in a non-complex context, or even guarantee that a given fixed complex
expression will yield the same "is or isn't?" answer across platforms or
releases, the best you can say about it is "implementation defined -- use at
your own risk".  I'd rather force the issue in my code by explicitly tossing
the imaginary component.  Note that this implies all numeric types should
grow .real and .imag attributes (else code can't be generic, or has to
resort to type checks, or maybe just

    try:
        x = x.real
    except AttributeError:
        pass

is good enough).

Another possibility for x-platform x-release consistency is to keep and
maintain an "exact?" bit with numbers, and barf on a complex value with a
non-exact 0 imaginary part.  This isn't really useful, though, unless e.g.
the exact bit remains set for 24./4. but not 24./5. (assuming the inputs are
exact), and then carefully defining when exactness is and isn't preserved is
a major undertaking.

BTW, I'm more a fan of Common Lisp's concessions to numeric reality than to
Scheme's attempt to wish numeric unpleasantness away.  CL generally allows
for "upward" conversion by magic, but generally never "downward".  So, e.g.,
CL's divmod equivalent allows int, ratio and float arguments, but never
complex.  That's a recipe for x-platform sanity <wink>.  See

http://www.math.uio.no/cltl/clm/node121.html#SECTION001600000000000000000

and especially

http://www.math.uio.no/cltl/clm/node130.html#SECTION001660000000000000000