Reputation: 103
When using floor division in python3 (and probably also python2 with import __future__
):
>>> 2//2
1
the output is an integer as expected. But as soon as one operand is a float, you get a float as result
>>> 2.0//2.0
1.0
>>> 2.0//2
1.0
>>> 2//2.0
1.0
I guess this is intended, but actually I don't understand, why it is supposed to be like this. What is the design concept of using a not previously determined data type as a result of an operation that always yields an integer?
The best a really extensive search gave me (from PEP 238)
Semantics of Floor Division
Floor division will be implemented in all the Python numeric types, and will have the semantics of
a // b == floor(a/b)
except that the result type will be the common type into which a and b are coerced before the operation.
Specifically:
- If a and b are of the same type, a//b will be of that type too. - If the inputs are of different types, they are first coerced to a common type using the same rules used for all other arithmetic operators.
In particular:
- if a and b are both ints or longs, the result has the same type and value as for classic division on these types (including the case of mixed input types; `int//long` and `long//int` will both return a long). - For floating point inputs, the result is a float. For example: `3.5//2.0 == 1.0` - For complex numbers, // raises an exception, since floor() of a complex number is not allowed. - For user-defined classes and extension types, all semantics are up to the implementation of the class or type.
But this still doesn't explain WHY the behavior is implemented like this.
Upvotes: 1
Views: 548
Reputation: 48962
This makes floor division consistent with the other arithmetic operations. The advantage is that instead of remembering that //
is a special case, you can use your existing knowledge and coding patterns. And as with all the other operators, if you want to force the output to be an int
you should explicitly coerce it to be such.
Upvotes: 0
Reputation: 87281
One possible advantage can be the following: If the inputs of an operation are float
s, then usually the most useful output type is a float
, because the program is doing floating point calculations. Similarly, if the inputs of an operation are integers (int
s or long
s), then usually the most useful output type is an integer.
A related surprising data point:
>>> str(int(123e300 // 10.0))
'12300000000000000348405169443457756499452463917650245579212965288916278422109198944984236481408634018703901759913201583616648277756338685989513894763895354330869046350917957229381143786183918719192956157930593465276658607709014541611368487360619735051905095032755082564499801643679232993692080863707136'
It's surprising, because it's natural to expect lots of 0
s at the end. You get other digits because of the limited precision of the float
type.
So by returning a float
, //
indicates that the output can be inaccurate.
Upvotes: 6