Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!goblin1!goblin.stu.neva.ru!uio.no!news.tele.dk!news.tele.dk!small.news.tele.dk!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.004 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'argument': 0.05; 'true,': 0.05; '*is*': 0.09; 'claimed': 0.09; 'exception,': 0.09; 'exception.': 0.09; 'false,': 0.09; 'raises': 0.09; 'subject:Why': 0.09; 'python': 0.11; '42,': 0.16; 'all).': 0.16; 'division.': 0.16; 'inf': 0.16; 'nan': 0.16; 'return,': 0.16; 'exception': 0.16; 'wrote:': 0.18; 'wed,': 0.18; 'bit': 0.19; 'trying': 0.19; 'thu,': 0.19; '>>>': 0.22; 'mathematical': 0.24; 'possibly': 0.26; 'header:In-Reply-To:1': 0.27; 'point': 0.28; 'chris': 0.29; 'am,': 0.29; 'raise': 0.29; "doesn't": 0.30; 'returned': 0.30; 'message- id:@mail.gmail.com': 0.30; "i'm": 0.30; '(which': 0.31; 'usually': 0.31; '(although': 0.31; '>>>>': 0.31; 'mod': 0.31; 'omitted': 0.31; 'origin': 0.31; 'sep': 0.31; 'another': 0.32; '(i.e.': 0.33; 'actual': 0.34; '"the': 0.34; 'sense': 0.34; 'could': 0.34; 'agree': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; 'really': 0.36; 'edge': 0.36; 'raising': 0.36; 'returning': 0.36; "didn't": 0.36; 'possible': 0.36; 'should': 0.36; 'too': 0.37; 'two': 0.37; 'to:addr:python-list': 0.38; 'to:addr:python.org': 0.39; 'even': 0.60; 'ian': 0.60; 'first': 0.61; 'account': 0.65; 'talking': 0.65; 'note:': 0.66; 'here': 0.66; 'behavior': 0.77; 'case?': 0.84; 'skip:4 20': 0.91; 'thing,': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=+7EFcI0PwcK0Z1BTPC7XqHLeheE1LZNAemGBI/GpN8Y=; b=0a3DCkfj11i+RYs78l5bz3E4JmArRl/meO4z6CpkBI166UXIWMAYf2o/ByZ/GSJRlR AKMopm4GMHa05/4Iwzi6V0quqLddmxs/ik4sEO6w4iIBDq4tNYoBujCz60mYDhW48x+m IV7KW4Cbm5Lpo+v6l2TZJKJ/UN59l1flejjvV6ePEeftCekqDdRUoeTv8iGyL4+TI44O 5q6wDypbD8jNaWiD9zbQY8wfck35Q2AWjaG/FjBlyK7uHiAfjxJplSVqE8ocgyAwK/eP rGigAJJIG3T6f8SeA1xheKFvm0ZkoKDSBtZ0qZbmppGTB9OVkD65AhNNdONGQh5zKzqX phhQ== X-Received: by 10.194.78.4 with SMTP id x4mr52132432wjw.44.1410970379008; Wed, 17 Sep 2014 09:12:59 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: References: <06397cb3-8baf-4af1-8152-ff7c3f6ceb62@googlegroups.com> <151e45ce-444d-441c-b59b-67e2aee3882b@googlegroups.com> From: Ian Kelly Date: Wed, 17 Sep 2014 10:12:18 -0600 Subject: Re: Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))` To: Python Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 40 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1410970380 news.xs4all.nl 2882 [2001:888:2000:d::a6]:45208 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:77975 On Wed, Sep 17, 2014 at 9:40 AM, Chris Angelico wrote: > On Thu, Sep 18, 2014 at 1:34 AM, Ian Kelly wrote: >> On Wed, Sep 17, 2014 at 9:29 AM, Chris Angelico wrote: >>> On Thu, Sep 18, 2014 at 1:16 AM, cool-RR wrote: >>>> I didn't ask for the modulo, I agree it should remain NaN. I'm talking about the floor division. >>>> >>> >>> Invariant: div*y + mod == x. >>> >>> If mod is NaN, there is no possible value for div that will make the >>> invariant true, ergo it too has to be NaN. >> >> That still doesn't make the invariant true. By this argument div could >> be 42, and the invariant would hold equally well (i.e. not at all). > > Nothing can possibly make it true, so there are only two > possibilities: return NaN, or raise an exception. I could see raising an exception, since the docs state "the result is (q, a % b), where q is usually math.floor(a / b) but may be 1 less than that" and it's already been established that math.floor(float('inf')) raises an exception (although interesting note: in Python 2 the docs claimed the same thing, but math.floor(float('inf')) returned float('inf') and divmod already returned float('nan'); so I don't think that the behavior of math.floor is really the origin of this). But the point I'm trying to make is that returning NaN here is every bit as arbitrary as returning None or False, because there *is* a value that makes actual mathematical sense to return, even if it fails to maintain the invariant on account of the modulus addition (which should just be omitted in this case). Here's another edge case that fails the invariant. Why should divmod return inf here but not in the first case? >>> divmod(1e300, 1e-300) (inf, 4.891554850853602e-301) >>> _[0] * 1e-300 + _[1] inf