On Thu, Sep 18, 2014 at 12:31 PM, Alexander Belopolsky firstname.lastname@example.org wrote:
On Thu, Sep 18, 2014 at 1:27 PM, Case Van Horsen email@example.com wrote:
The ISO C99/C11 (Annex F) (and POSIX and IEEE-754) standards define a function called "roundToIntegralTowardsNegative". For the special value +Inf, it specifies a return value of +Inf.
However, the integral value returned is still an IEEE-754 formatted value and can return +Inf. PEP-3141 changed the behavior of math.floor() (and __floor__ in general) to return an actual integer. That makes it impossible to comply with ISO etc. standards.
I don't think there is any dispute over what math.floor(inf) should return. POSIX, C99, IEEE and probably many other standards agree that inf should be returned as long as the resulting type can represent it.
I dispute that there is no dispute over what math.floot(inf) should return. ;-)
All the standards specify a result type can represent +-Inf and +-0. A standards compliant version should return +-Inf and +-0. lrint() and llrint() are defined to return long or long long, respectively. It would be fine if they raised an exception. The current math.floor() actually behaves more like llrint() than floor().
I accpet that having math.floor() return an integer (and raise an exception for +-Inf) may be useful in many cases but it is different from the standard. Other floating-point libraries still return a floating-point value.
Disclaimer: I maintain gmpy2.
Note that before math.floor() was changed to return int in 3.x, we had
The question here is not about floor, but about floor_division. NumPy implements it as simple-minded floor(x/y), while Python attempts to be more precise by doing floor((x - fmod(x, y))/y).
$ hg blame -d -u -w Objects/floatobject.c nascheme Thu Jan 04 01:44:34 2001 +0000: float_divmod(PyObject *v, PyObject *w) .. guido Sun Oct 20 20:16:45 1991 +0000: mod = fmod(vx, wx); tim Sat Sep 16 03:54:24 2000 +0000: /* fmod is typically exact, so vx-mod is *mathematically* an guido Thu May 06 14:26:34 1999 +0000: exact multiple of wx. But this is fp arithmetic, and fp guido Thu May 06 14:26:34 1999 +0000: vx - mod is an approximation; the result is that div may guido Thu May 06 14:26:34 1999 +0000: not be an exact integral value after the division, although guido Thu May 06 14:26:34 1999 +0000: it will always be very close to one. guido Thu May 06 14:26:34 1999 +0000: */ guido Sun Oct 20 20:16:45 1991 +0000: div = (vx - mod) / wx; ..
Given that this logic dates back to 1991, I doubt not-finite case was seriously considered.
In light of PEP 3141, if anything should be done about float // float it would be to make it return and int and as a consequence inf // 1 should raise an OverflowError.
Since divmod() and floor_division aren't defined by a standard, Python can define its own standard. But each time Python changes behavior, external libraries will need to change, or not; and another difference between Python versions is introduced.