On Mon, 21 Apr 2014 09:24:09 +1000, Chris Angelico wrote: > On Mon, Apr 21, 2014 at 8:52 AM, Gregory Ewing > <greg.ew...@canterbury.ac.nz> wrote: >> Chris Angelico wrote: >> >>> Truncating vs true is not the same as int vs float. If you mean to >>> explicitly request float division, you call float() on one or both >>> arguments. You're being explicit about something different. >> >> >> If you know you're dealing with either ints or floats, which is true in >> the vast majority of cases, then you know that / will always perform >> float division. > > And that's what I mean about the common non-trivial case. It's easy > enough to come up with contrived or trivial cases that use any types, > but in most cases, it'd be fine to explicitly call float() on one of the > operands to explicitly request floating-point division. Choosing between > two division operators is not the same thing as choosing a data type.
Nobody says that they are. Choosing between / and // means to choose between two different operator. / performs true division, the sort that you learn about in school (modulo the usual floating point issues -- floats are not mathematical reals). // performs division which floors towards negative infinity. (For positive values, that's equivalent to truncation.) Hence the two special methods: __truediv__ and __floordiv__ (plus the reversed __r*__ versions). I think you need to stop thinking about "integer division", because (1) "integer division" is not well-defined, and (2) in the general case, // doesn't return an int, although it should return a value that is integer valued. Why is integer division not well-defined? Because division of integers doesn't necessarily return an integer: the integers are not closed with the division operator. Cases like 10/5 are easy, that's just 2. What about 11/5 or -7/3? I can think of at least six things that "integer division" might do in those cases: - round to nearest, ties round to even ("banker's rounding"); - round to nearest, ties round to odd; - round towards positive infinity (ceiling); - round towards negative infinity (floor); - round towards zero (truncate); - raise an exception; so before talking about "integer division" we have to decide which of those apply. Python doesn't talk about integer division, well not officially, but talks about *floor division*. The nice thing about this is that there's no requirement that it return an actual int: py> 11.0//2 5.0 just an integer-valued value. It's up to the class to decide how it works. > Explicitly choosing float division: > > x / float(y) But here you're not choosing an *operator*, you're choosing a *type*. With this model, how do I distinguish between floor division and true division using, say, Fractions? py> from fractions import Fraction as F py> F(1799, 27)/F(3) # True division. Fraction(1799, 81) py> F(1799, 27)//F(3) # Floor division. 22 Converting to floats is not an option, since (1) it returns a float, not a Fraction, and (2) it introduces rounding errors: py> F(1799, 27)/F(3) == F(1799, 27)/3.0 False [...] > Both explicit forms can be done cleanly without empowering the language > with the magic of int/int->float. It's hardly magic, and I really am having difficult in working out exactly what your objection to it is. Is it really as simple as "operations on ints should only return ints, like in C"? -- Steven D'Aprano http://import-that.dreamwidth.org/ -- https://mail.python.org/mailman/listinfo/python-list