Integer division

Discussion in 'Python' started by jm.suresh, Jun 7, 2007.

  1. jm.suresh

    jm.suresh Guest

    Hello all,
    I have two integers and I want to divide one by another, and want to
    get an integer result which is the higher side whenever the result is
    a fraction.
    3/2 => 1 # Usual behavior
    some_func(3, 2) => 2 # Wanted

    Any easier solution other than int(math.ceil(float(3)/2))

    -
    Suresh
     
    jm.suresh, Jun 7, 2007
    #1
    1. Advertisements

  2. The normal solution is to add (divisor-1) to the dividend before division.

    Ie ceil(3/2) = floor((3+(2-1))/2) = 2. Correct.

    But ceil(4/2) = floor((4+(2-1))/2) = 2 also. Correct.



    Hamish
     
    Hamish Moffatt, Jun 7, 2007
    #2
    1. Advertisements

  3. jm.suresh

    jm.suresh Guest

    What about this?
    .... if a%b:
    .... return ((a/b)+1)
    .... else:
    .... return (a/b)
    ....3
     
    jm.suresh, Jun 7, 2007
    #3
  4. def some_func(a, b):
    return -(-a/b)

    And people complain about Python's behaviour regarding division of
    negative integers.
     
    Sion Arrowsmith, Jun 7, 2007
    #4
  5. Yes, although it's not as short or as fast (probably as my version):

    def div_ceil(a, b):
    return ((a+(b-1))/b)



    Hamish
     
    Hamish Moffatt, Jun 7, 2007
    #5
  6. If that's what you care about:

    $ python -mtimeit -s 'def divc1(a,b): return (a+b-1)/b' 'divc1(3,2)'
    1000000 loops, best of 3: 0.443 usec per loop
    $ python -mtimeit -s 'def divc2(a,b): return -(-a/b)' 'divc2(3,2)'
    1000000 loops, best of 3: 0.331 usec per loop

    Also, note:
    1073741824L

    which is going to cause problems with sys.version_info < (2, 3) .
    (Or do I mean (2, 2)? I don't have a 2.2 to hand.)
     
    Sion Arrowsmith, Jun 7, 2007
    #6
  7. jm.suresh

    Terry Reedy Guest

    | > 3/2 => 1 # Usual behavior
    | > some_func(3, 2) => 2 # Wanted
    |
    | def some_func(a, b):
    | return -(-a/b)
    |
    | And people complain about Python's behaviour regarding division of
    | negative integers.

    Nice. This goes on my 'why didn't I think of that' list;-)

    I was thinking of the rather pedestrian

    d,r = divmod(a,b)
    if r: d+=1

    tjr
     
    Terry Reedy, Jun 7, 2007
    #7
  8. Are you trying to accomplish int((a/b) + 0.5), but cheaply?

    If so, consider that that is the same as (a/b) + (b/2b),
    which is (2a/2b) + (b/2b), which is (2a+b)/2b.

    Since this just involves doubling you can avoid multiplying altogether
    and just use this:

    def rounddiv(a,b):
    return int((a+a+b)/(b+b))

    That's 3 integer adds and 1 integer divide. The int() cast is just
    there is case somebody passes in floats for a or b; if you know you're
    only going to have integer arguments you don't need it.
     
    Some Other Guy, Jun 8, 2007
    #8
  9. jm.suresh

    Dan Bishop Guest

    The // operator was added to the language for a reason. I'm surprised
    at how few Pythonistas are using it six years later.
     
    Dan Bishop, Jun 8, 2007
    #9
  10. jm.suresh

    Terry Reedy Guest

    | wrote:
    |
    | > Hello all,
    | > I have two integers and I want to divide one by another, and want to
    | > get an integer result which is the higher side whenever the result is
    | > a fraction.
    | > 3/2 => 1 # Usual behavior
    | > some_func(3, 2) => 2 # Wanted
    |
    | Are you trying to accomplish int((a/b) + 0.5), but cheaply?

    No, the OP wanted 'ceiling' division rather than 'floor' division.
    In other words, always round up instead of down.

    | If so, consider that that is the same as (a/b) + (b/2b),
    | which is (2a/2b) + (b/2b), which is (2a+b)/2b.

    This is nice for rounded division.

    tjr
     
    Terry Reedy, Jun 8, 2007
    #10
  11. It would just document intent here because it still gives `float` results
    if used with at least one `float` as operands:

    In [1]: 10.0 // 2
    Out[1]: 5.0

    Ciao,
    Marc 'BlackJack' Rintsch
     
    Marc 'BlackJack' Rintsch, Jun 8, 2007
    #11
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.