274

Consider this division in Python 3:

>>> 2/2
1.0

Is this intended? I strongly remember earlier versions returning int/int = int. What should I do? Is there a new division operator or must I always cast?


In 2.x, the behaviour was indeed reversed; see How can I force division to be floating point? Division keeps rounding down to 0? for the opposite, 2.x-specific problem.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Jonas Byström
  • 25,316
  • 23
  • 100
  • 147
  • 38
    Yes, that's the way division works in 3.x. – hughdbrown Aug 15 '09 at 22:49
  • 3
    Here's a post by Python's creator talking about how the rounding works, it's orthogonal to your question but I found it interesting: http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html – Aaron D Feb 28 '13 at 16:59
  • @hughdbrown so that means for **all** python 3 version essentially? – Charlie Parker Feb 24 '17 at 22:36
  • @hughdbrown: yes, [PEP](https://www.python.org/dev/peps/pep-0238/) is *final*, meaning both accepted and implemented. – Jonas Byström Mar 02 '17 at 09:40
  • If you are doing anything other than simple division, then casting the float result is a better method. For example, calculating 480 // 640 * 320 results in 0 – brianlmerritt May 06 '21 at 05:47
  • 1
    @brianlmerritt depends on what you're doing and *why*. Working in integer arithmetic is more straightforward, and problems with precision can typically be addressed by just making sure that multiplications happen before divisions: `480 * 320 // 640` wives the expected `240`. – Karl Knechtel Oct 13 '22 at 18:19

4 Answers4

328

Take a look at PEP-238: Changing the Division Operator

The // operator will be available to request floor division unambiguously.

Brandon E Taylor
  • 24,881
  • 6
  • 47
  • 71
  • 12
    @JonathanSternberg except for all the code that was written for python 2.0. I feel like the role of / and // should be reversed to keep backwards compatibility. Also, in pretty much every other language / preserves type. i would make more sense then for // to automatically convert to float, not /. – thang Sep 11 '17 at 20:22
  • 3
    The second part (after the "Also") makes sense (similarity to other languages) but regarding the first part, the whole _point_ of Python 3 was to NOT be backwards compatible with Python 2, but rather fix up a bunch of problems with Python 2. Enough people found the ambiguity of `/` to be enough of a language design "mistake" that needed to be fixed in Python 3. It may have been a controversial decision, but enough people felt it was the correct one. Count me in the group that loves the change. It is nice we can all agree to disagree. Cheers. :) – Ray Toal Aug 07 '19 at 02:39
  • I understand the reason why Python does it in the instances of the answer not being #.0, but not for instances where the answer is #.0. Float 1.0 is the same as integer 1, so when the numbers being calculated are integers that result in a float that's the equivalent of an integer, why not just return or print an integer? That at least keeps the types consistent and intuitive. If an answer would include a non-zero decimal number, then the float should be returned. Other languages I've used work this way (smartly), none of them return #.0 when the answer is an integer. – SteveExdia Feb 02 '23 at 17:51
76

Oops, immediately found 2//2. This will output an int rather than a float.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Jonas Byström
  • 25,316
  • 23
  • 100
  • 147
  • 1
    This seems to not work for negative numbers. -1//5 return -1 and -5//5 returns -1. – michael.schuett Mar 25 '19 at 01:25
  • 1
    @mschuett: this is to be expected, and is the same result as with Python 2. – Jonas Byström Mar 26 '19 at 14:56
  • 1
    Yeah I did some more digging and found that out as well. However I would imagine a decent size number of people do not realize this depending on the language they come from. – michael.schuett Mar 26 '19 at 15:19
  • @TylerH I doubt there was any confusion in the past 12 years that warranted your edit? – Jonas Byström Jul 05 '21 at 14:36
  • @JonasByström The upvoted comments asking for clarification and giving that clarification weren't a clue? Hard to see how one *wouldn't* see an obvious opportunity for improvement from the original version of the answer. Good answers provide the solution *and* an explanation of said solution. Readers might otherwise use `//` instead of `/` because of this answer and cause code that depends on a float to break, not realizing the implications. – TylerH Jul 05 '21 at 15:12
  • `//` only yields an int if the two divisors are ints. – eric Nov 14 '21 at 04:54
  • @eatingthenight please see [What is the reason for difference between integer division and float to int conversion in python?](https://stackoverflow.com/questions/59304235). – Karl Knechtel Oct 13 '22 at 18:16
58

Behavior of the division operator in Python 2.7 and Python 3

In Python 2.7: By default, division operator will return integer output.

To get the result in double, multiply the dividend or divisor by 1.0.

100/35 => 2 # Expected is 2.857142857142857
(100*1.0)/35 => 2.857142857142857
100/(35*1.0) => 2.857142857142857

In Python 3

// => used for integer output
/ => used for double output

100/35 => 2.857142857142857
100//35 => 2
100.//35 => 2.0    # Floating-point result if the divisor or dividend is real
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
VijayNaidu
  • 716
  • 5
  • 5
  • 4
    By the way, no need to multiply by 1.0. It is enough that one of the numbers is a float. E.g., 100/35.0 = 100.0/35 = 2.857142857142857 – Tal J. Levy Oct 08 '18 at 09:26
  • 3
    `//` is not "used for integer output". `//` is the result of the `floor()` function to the result of the division, which in turns yields an integer if the two operands are integers and a float if at least one of them is a float, for types coherence. – Olivier Mar 11 '21 at 12:59
25

The accepted answer already mentions PEP 238. I just want to add a quick look behind the scenes for those interested in what's going on without reading the whole PEP.

Python maps operators like +, -, * and / to special functions, such that e.g. a + b is equivalent to

a.__add__(b)

Regarding division in Python 2, there is by default only / which maps to __div__ and the result is dependent on the input types (e.g. int, float).

Python 2.2 introduced the __future__ feature division, which changed the division semantics the following way (TL;DR of PEP 238):

  • / maps to __truediv__ which must "return a reasonable approximation of the mathematical result of the division" (quote from PEP 238)
  • // maps to __floordiv__, which should return the floored result of /

With Python 3.0, the changes of PEP 238 became the default behaviour and there is no more special method __div__ in Python's object model.

If you want to use the same code in Python 2 and Python 3 use

from __future__ import division

and stick to the PEP 238 semantics of / and //.

code_onkel
  • 2,759
  • 1
  • 16
  • 31