When is divmod(a,b)[0] == floor(a/b)-1 ?

Discussion in 'Python' started by kj, Sep 24, 2009.

  1. kj

    kj Guest

    The docs for divmod include the following:

    divmod(a, b)
    ...For floating point numbers the result is (q, a % b), where q
    is usually math.floor(a / b) but may be 1 less than that. ...

    I know that floating point math can sometimes produce "unexpected"
    results, so the above caveat is not entirely surprising. Still,
    I would find it helpful to see a specific example where
    divmod(a, b)[0] is equal to math.floor(a/b)-1. Does anybody know
    one?

    Thanks!

    kynn
    kj, Sep 24, 2009
    #1
    1. Advertising

  2. kj

    Robert Kern Guest

    On 2009-09-24 14:40 PM, kj wrote:
    >
    > The docs for divmod include the following:
    >
    > divmod(a, b)
    > ...For floating point numbers the result is (q, a % b), where q
    > is usually math.floor(a / b) but may be 1 less than that. ...
    >
    > I know that floating point math can sometimes produce "unexpected"
    > results, so the above caveat is not entirely surprising. Still,
    > I would find it helpful to see a specific example where
    > divmod(a, b)[0] is equal to math.floor(a/b)-1. Does anybody know
    > one?


    In [21]: a = 10.0

    In [22]: b = 10.0 / 3.0

    In [24]: divmod(a, b)[0]
    Out[24]: 2.0

    In [25]: math.floor(a / b) - 1.0
    Out[25]: 2.0

    --
    Robert Kern

    "I have come to believe that the whole world is an enigma, a harmless enigma
    that is made terrible by our own mad attempt to interpret it as though it had
    an underlying truth."
    -- Umberto Eco
    Robert Kern, Sep 24, 2009
    #2
    1. Advertising

  3. kj

    kj Guest

    In <> Robert Kern <> writes:

    >On 2009-09-24 14:40 PM, kj wrote:
    >>
    >> The docs for divmod include the following:
    >>
    >> divmod(a, b)
    >> ...For floating point numbers the result is (q, a % b), where q
    >> is usually math.floor(a / b) but may be 1 less than that. ...
    >>
    >> I know that floating point math can sometimes produce "unexpected"
    >> results, so the above caveat is not entirely surprising. Still,
    >> I would find it helpful to see a specific example where
    >> divmod(a, b)[0] is equal to math.floor(a/b)-1. Does anybody know
    >> one?


    >In [21]: a = 10.0


    >In [22]: b = 10.0 / 3.0


    >In [24]: divmod(a, b)[0]
    >Out[24]: 2.0


    >In [25]: math.floor(a / b) - 1.0
    >Out[25]: 2.0


    Wow. To me this stuff is just black magic, with a bit of voodoo
    added for good measure... Maybe some day I'll understand it.

    Thanks!

    kynn
    kj, Sep 24, 2009
    #3
  4. >> In [21]: a = 10.0
    >
    >> In [22]: b = 10.0 / 3.0

    >
    >> In [24]: divmod(a, b)[0]
    >> Out[24]: 2.0

    >
    >> In [25]: math.floor(a / b) - 1.0
    >> Out[25]: 2.0

    >
    > Wow. To me this stuff is just black magic, with a bit of voodoo
    > added for good measure... Maybe some day I'll understand it.


    I think this example is not too difficult to understand (IIUC).
    I'll use integer constants to denote exact real numbers and
    exact real operations, and the decimal point to denote floating
    point numbers.

    IIUC, the source of the problem is that 10.0/3.0 > 10/3. 10/3
    is not exactly representable, so it needs to be rounded up or
    rounded down; the closest representable value is larger than
    the exact value.

    Therefore, (10.0/3.0)*3 > 10. So 10.0/3.0 doesn't fit three times
    into 10.0, but only two times; the quotient is therefore 2.0.
    The remainder is really close to 10.0/3.0, though:

    py> divmod(a,b)
    (2.0, 3.333333333333333)
    py> divmod(a,b)[1]-b
    -4.4408920985006262e-16

    So that explains why you get 2.0 as the quotient.

    Now, if you do math.floor(a / b), we first need to look at
    a/b. Again, 10.0/(10.0/3.0) is not exactly representable. Funnily,
    the closest representable value is 3.0, so the quotient gets rounded
    up again:

    py> a/b
    3.0

    math.floor doesn't change the value, so it stays at 3.0; qed.

    Regards,
    Martin
    Martin v. Löwis, Sep 27, 2009
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. SpaceCowboy
    Replies:
    6
    Views:
    1,071
    Josef Garvi
    Aug 15, 2003
  2. John
    Replies:
    3
    Views:
    335
    Chris Smith
    Feb 11, 2005
  3. Ethan Furman
    Replies:
    3
    Views:
    377
    Ken Starks
    Jul 16, 2008
  4. Gnarlodious

    Boolean result of divmod

    Gnarlodious, Jun 21, 2011, in forum: Python
    Replies:
    3
    Views:
    183
    Terry Reedy
    Jun 21, 2011
  5. Dirk Traulsen

    Bug: Numeric#divmod calculates wrongly

    Dirk Traulsen, Oct 8, 2007, in forum: Ruby
    Replies:
    11
    Views:
    226
    Axel Etzold
    Oct 15, 2007
Loading...

Share This Page