[Guido] > ... > So you are proposing that Decimal also rip out the % and // operators > and __divmod__? WFM, but I don't know what Decimal users say (I'm not > one).
Yes: it's just as much a floating type as HW binary floats, and all the same issues come up. For example, decimal floats are just as prone to the floor division surprise Raymond started this thread with; e.g., >>> a Decimal("2.172839486617283948661728393E+29") >>> b Decimal("1234567890123456789012345678") >>> a / b Decimal("176.0000000000000000000000000") >>> a/b == 176 True >>> a // b Decimal("175") That is, floor division of `a` by `b` isn't necessarily the same as the floor of `a` divided by `b` for decimal floats either, and for exactly the same reason as when using binary floats: a/b can suffer a rounding error due to finite precision, but floor division computes the floor of the quotient "as if" infinite precision were available. At least using `decimal` it's easy to /explain/ just by boosting the precision: >>> decimal.getcontext().prec *= 2 >>> a / b Decimal("175.99999999999999999999999997731999979587999814250798308") This shows quite clearly why a/b rounded up to exactly 176 when working with half this precision. There's also that the decimal __mod__ implementation is like math.fmod for binary floats, not like Python's int/long __mod__. Having just one builtin meaning for numeric `%` as an infix operator is a good thing, and the int/long meaning is both by far the most common use but only "works" for types with exactly representable results (ints and longs built in; rationals if someone adds them; ditto constructive reals; ... -- but not floats). > ... > For ints and floats, real could just return self, and imag could > return a 0 of the same type as self. Cool! Works for me. > I guess the conjugate() function could also just return self (although I see > that conjugate() for a complex with a zero imaginary part returns > something whose imaginary part is -0; is that intentional? That's wrong, if true: it should return something with the opposite sign on the imaginary part, whether or not that equals 0 (+0. and -0. both "equal 0"). This is harder to check than it should be because it appears there's a bug in the complex constructor (at least in Python 2.5): complex(1., 0.0) and complex(1., -0.0) both appear to create a complex with a +0 imaginary part: >>> def is_minus_0(x): ... import math ... return x == 0.0 and math.atan2(x, x) != 0 >>> is_minus_0(+0.0) # just showing that "it works" False >>> is_minus_0(-0.0) # ditto True >>> is_minus_0(complex(1, 0.0).imag) False >>> is_minus_0(complex(1, -0.0).imag) # should be True False OTOH, the complex constructor does respect the sign of the real part: >>> is_minus_0(complex(0.0, 0.0).real) False >>> is_minus_0(complex(-0.0, 0.0).real) True complex_new() ends with: cr.real -= ci.imag; cr.imag += ci.real; and I have no idea what that thinks it's doing. Surely this isn't intended?!: >>> complex(complex(1.0, 2.0), complex(10.0, 20.0)) (-19+12j) WTF? In any case, that's also what's destroying the sign of the imaginary part in complex(1.0, -0.0). Knowing that a -0 imaginary part can't be constructed in the obvious way: >>> is_minus_0(complex(0, 0).conjugate().imag) True So conjugate() does flip the sign on a +0 imaginary part, and: >>> is_minus_0(complex(0, 0).conjugate().conjugate().imag) False so it also flips the sign on a -0 imaginary part. That's all as it should be. Hmm. You meant to ask something different, but I actually answered that too ;-) > I'd rather not have to do that when the input is an int or float, what do you > think?) Returning `self` is fine with me for those, although, e.g., it does mean that (3).conjugate().imag and (complex(3)).conjugate().imag are distinguishable with enough pain. I don't care. I think of integers and floats as "not having" an imaginary part more than as having a 0 imaginary part (but happy to invent a 0 imaginary part if someone asks for one). _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com