# Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))` Classic List Threaded 31 messages 12
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 While debugging my code I found that the bug was because I assumed that something like `divmod(float('inf'), 1)` would be equal to `(float('inf'), float('nan'))`, while Python returns `(float('nan'), float('nan'))`. Why does Python make the division result be NaN in this case? `float('inf') / 1` is still `float('inf')`. Thanks, Ram.
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 On 9/16/2014 5:40 PM, cool-RR wrote: > While debugging my code I found that the bug was because I assumed > that something like `divmod(float('inf'), 1)` would be equal to > `(float('inf'), float('nan'))`,  while Python returns `(float('nan'), > float('nan'))`. Why does Python make the division result be NaN in > this case? `float('inf') / 1` is still `float('inf')`. For integers, divmod(x, y) is defined as (x // y, x % y) == ((x - x%y) // y, x % y) == ((x - x%y) / y, x % y). For floats, Python is documented as using the third expression. "Help on built-in function divmod in module builtins: divmod(...)      divmod(x, y) -> (div, mod)      Return the tuple ((x-x%y)/y, x%y).  Invariant: div*y + mod == x." It does not really matter, however, as infinity cannot be 'floored' as required for //  >>> math.floor(float('inf')) Traceback (most recent call last):    File "", line 1, in      math.floor(float('inf')) OverflowError: cannot convert float infinity to integer and hence  >>> float('inf') // 1.0 nan -- Terry Jan Reedy
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 In reply to this post by cool-RR Terry, that doesn't really answer the question "why", it just pushes it back to the documentation. Is there a real answer why? Why return NaN when Inf would make mathematical sense? On Wednesday, September 17, 2014 4:13:38 AM UTC+3, Terry Reedy wrote: > On 9/16/2014 5:40 PM, cool-RR wrote: > > > While debugging my code I found that the bug was because I assumed > > > that something like `divmod(float('inf'), 1)` would be equal to > > > `(float('inf'), float('nan'))`,  while Python returns `(float('nan'), > > > float('nan'))`. Why does Python make the division result be NaN in > > > this case? `float('inf') / 1` is still `float('inf')`. > > > > For integers, divmod(x, y) is defined as (x // y, x % y) == ((x - x%y) > > // y, x % y) == ((x - x%y) / y, x % y). > > > > For floats, Python is documented as using the third expression. > > > > "Help on built-in function divmod in module builtins: > > divmod(...) > >      divmod(x, y) -> (div, mod) > >      Return the tuple ((x-x%y)/y, x%y).  Invariant: div*y + mod == x." > > > > It does not really matter, however, as infinity cannot be 'floored' as > > required for // > > > >  >>> math.floor(float('inf')) > > Traceback (most recent call last): > >    File "", line 1, in > >      math.floor(float('inf')) > > OverflowError: cannot convert float infinity to integer > > > > and hence > > > >  >>> float('inf') // 1.0 > > nan > > > > -- > > Terry Jan Reedy
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 On Thu, Sep 18, 2014 at 12:55 AM, cool-RR wrote: > Terry, that doesn't really answer the question "why", it just pushes it back to the documentation. Is there a real answer why? Why return NaN when Inf would make mathematical sense? > To answer that, we have to first look at what it means to do operations on Inf. The definition of "Infinity + 1" is the limit of "x + 1" as x goes toward positive infinity - which is positive infinity. Same with infinity-1, infinity/1, infinity*1, etc, etc, etc. So far, so good. But as x tends toward positive infinity, the value of "x // 1" (or simply of floor(x)) doesn't simply increase tidily. It goes up in little jumps, every time x reaches a new integer. And while it's conceivable to define that infinity divided by anything is infinity, and infinity modulo anything is zero, that raises serious issues of primality and such; I'm not sure that that would really help anything. So there's no possible value for floor division of infinity, ergo the result is NaN. So. There you have an answer. Now, for your next question, can you please use something better than Google Groups, or at least learn how to use an interleaved posting style and trim out all the excess blank lines? Thanks. ChrisA
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 In reply to this post by cool-RR On Wednesday, September 17, 2014 6:10:35 PM UTC+3, Chris Angelico wrote: > On Thu, Sep 18, 2014 at 12:55 AM, cool-RR wrote: > > Terry, that doesn't really answer the question "why", it just pushes it back to the documentation. Is there a real answer why? Why return NaN when Inf would make mathematical sense? > > > To answer that, we have to first look at what it means to do > operations on Inf. The definition of "Infinity + 1" is the limit of "x > + 1" as x goes toward positive infinity - which is positive infinity. > Same with infinity-1, infinity/1, infinity*1, etc, etc, etc. So far, > so good. But as x tends toward positive infinity, the value of "x // > 1" (or simply of floor(x)) doesn't simply increase tidily. It goes up > in little jumps, every time x reaches a new integer. Despite the fact it goes up in jump, it still satisfies the mathematical condition needed for a limit. (I won't quote the epsilon-delta thing but I think you can find it.) > And while it's > conceivable to define that infinity divided by anything is infinity, > and infinity modulo anything is zero, that raises serious issues of > primality and such; > I'm not sure that that would really help anything. I didn't ask for the modulo, I agree it should remain NaN. I'm talking about the floor division. I don't see any problems this will cause with primality. "I'm not sure that that would really help anything" is a little bit too vague. Thanks, Ram.
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 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. ChrisA
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 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).
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 In reply to this post by Terry Reedy On Tue, Sep 16, 2014 at 7:12 PM, Terry Reedy wrote: > It does not really matter, however, as infinity cannot be 'floored' as > required for // > >>>> math.floor(float('inf')) > Traceback (most recent call last): >   File "", line 1, in >     math.floor(float('inf')) > OverflowError: cannot convert float infinity to integer > > and hence > >>>> float('inf') // 1.0 > nan In C, floor(INFINITY) returns infinity (at least in the implementation I just tested).
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 In reply to this post by Ian Kelly-2 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. ChrisA
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 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) >>> _ * 1e-300 + _ inf
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 In reply to this post by Chris Angelico 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. Actually, I think we're focusing on the wrong element of the tuple. The fact is that there are values that can make the invariant true. For example, divmod(inf, 1) could return (inf, 0).  inf * 1 + 0 = inf. (inf, 1), or (inf, ) would work equally well.  The *only* reason the invariant can't be maintained is because we're committed to returning nan for the second element for some reason.
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 In reply to this post by cool-RR On Wednesday, September 17, 2014 6:30:04 PM UTC+3, 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. > ChrisA Chris, why is this invariant `div*y + mod == x` so important? Maybe it's more important to return a mathematically reasonable result for the the floor-division result than to maintain this invariant? Thanks, Ram.
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 On Thu, Sep 18, 2014 at 2:33 AM, cool-RR wrote: > On Wednesday, September 17, 2014 6:30:04 PM UTC+3, 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. >> ChrisA > > Chris, why is this invariant `div*y + mod == x` so important? Maybe it's more important to return a mathematically reasonable result for the the floor-division result than to maintain this invariant? It's important because it's documented :) You can expect whatever you like, but if something's a documented invariant, that's more important than your expectations. Now, why was divmod documented as returning values adhering to that invariant? You'd have to ask the developers, I've no idea. ChrisA
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 In reply to this post by Chris Angelico On Wed, Sep 17, 2014 at 9:10 AM, Chris Angelico wrote: > And while it's > conceivable to define that infinity divided by anything is infinity, > and infinity modulo anything is zero, that raises serious issues of > primality and such; I'm not sure that that would really help anything. I missed that this point was already discussed. Can you elaborate on the "serious issues of primality and such"? Since infinity is not a natural number, its primality is undefined, so I don't see the issue here.
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 On Thu, Sep 18, 2014 at 4:03 AM, Ian Kelly wrote: > On Wed, Sep 17, 2014 at 9:10 AM, Chris Angelico wrote: >> And while it's >> conceivable to define that infinity divided by anything is infinity, >> and infinity modulo anything is zero, that raises serious issues of >> primality and such; I'm not sure that that would really help anything. > > I missed that this point was already discussed. Can you elaborate on > the "serious issues of primality and such"? Since infinity is not a > natural number, its primality is undefined, so I don't see the issue > here. It's not something I've personally worked with, so I'm trying to dredge stuff up from my brain, but I think there's something along the lines of "stuff shouldn't be a multiple of everything" and the Prime Number Theorem. But that may just be a case where float != real. ChrisA
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 In reply to this post by cool-RR On 9/17/2014 10:55 AM, cool-RR wrote: > Terry, that doesn't really answer the question "why", it just pushes > it back to the documentation. Is there a real answer why? Why return > NaN when Inf would make mathematical sense? IEEE float('inf') and float('nan') are engineering, not math constructs. I showed that the result is consistent with the math definition. Another result (including raising) might be also.  Many choices concerting inf and nan are arbitrary and any 'why' can be debated. -- Terry Jan Reedy
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 In reply to this post by Ian Kelly-2 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: >>> 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. If nothing can make it true, then it is not an invariant, and your argument is no longer valid. -- Steven
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 In reply to this post by cool-RR cool-RR wrote: > Chris, why is this invariant `div*y + mod == x` so important? Maybe it's > more important to return a mathematically reasonable result for the the > floor-division result than to maintain this invariant? You keep talking about floor(inf) == inf being "mathematically reasonable", but I'm not convinced that it is. Can you justify why you think it is mathematically reasonable? Remember that IEEE-754 inf represents two different concepts: (1) A large but finite number which has overflowed. (2) Actual mathematical infinity ?. Even in the case of actual mathematical infinity, the result of floor(?) isn't clear to me. Floor is supposed to return an integer, how do you know that ? is integer valued? You can do ? % 1 to see what the fractional part is, but that gives NaN, so justify your belief that ? is integer-valued.  But *which* mathematical infinity? One of the cardinal infinities, the alephs, or one of the ordinal infinities, the omegas and the epsilons? (There are an infinite number of *all three*.) Is c just another name for aleph-1, or is distinct from all the alephs? Even professional mathematicians tread warily when doing arithmetic on infinities. -- Steven
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 In reply to this post by Ian Kelly-2 Chris Angelico wrote: > On Thu, Sep 18, 2014 at 4:03 AM, Ian Kelly wrote: >> On Wed, Sep 17, 2014 at 9:10 AM, Chris Angelico wrote: >>> And while it's >>> conceivable to define that infinity divided by anything is infinity, >>> and infinity modulo anything is zero, that raises serious issues of >>> primality and such; I'm not sure that that would really help anything. >> >> I missed that this point was already discussed. Can you elaborate on >> the "serious issues of primality and such"? Since infinity is not a >> natural number, its primality is undefined, so I don't see the issue >> here. > > It's not something I've personally worked with, so I'm trying to > dredge stuff up from my brain, but I think there's something along the > lines of "stuff shouldn't be a multiple of everything" and the Prime > Number Theorem. But that may just be a case where float != real. I don't think that the Prime Number Theorem has anything to say about transfinite numbers (infinities). It says that for sufficiently large values of n, the number of primes below n asymptotically approaches the the integral of 1/ln(x) between 2 and n: ?(n) ~ Li(n) (Note that in this case, ? is not pi = 3.1414... but is the "prime counting function", thus proving that no matter how famous or well-known a particular mathematical symbol is, somebody will insist on using it for something else.) http://mathworld.wolfram.com/PrimeNumberTheorem.htmlPerhaps you are thinking of the Fundamental Theorem of Arithmetic, which states that every positive integer except 1 can be uniquely factorized into a product of one or more primes? http://mathworld.wolfram.com/FundamentalTheoremofArithmetic.htmlBut that doesn't apply to infinity, which isn't an integer. -- Steven
Reply | Threaded
Open this post in threaded view
|

## Why `divmod(float('inf'), 1) == (float('nan'), float('nan'))`

 On Thu, Sep 18, 2014 at 1:29 PM, Steven D'Aprano wrote: > Perhaps you are thinking of the Fundamental Theorem of Arithmetic, which > states that every positive integer except 1 can be uniquely factorized into > a product of one or more primes? > > http://mathworld.wolfram.com/FundamentalTheoremofArithmetic.html> > But that doesn't apply to infinity, which isn't an integer. May have been that, or maybe was something different altogether. I was trying to relocate the info I'd been reading (ages ago), but without success. To be honest, I was hoping someone else would do the "Of course, I know what you mean" part for me :) But it's ended up more like the Goon Show: "How do you intend tipping Mount Everest on its side?" "Well, isn't it obvious?" with no result forthcoming. Sorry for the noise! Infinities are plenty weird, just this one specific weirdness wasn't right. ChrisA
12