Message335882
Thanks, Steven! I'll go on to suggest that the best intro to these issues for Python programmers is in Python's own tutorial:
https://docs.python.org/3/tutorial/floatingpoint.html
Raymond, `divmod(a, b)[0]` IS the mathematical `floor(a/b)`, where the latter is computed (as if) with infinite precision. Rounding `a/b` to a float _before_ taking the floor is quite different, and was never seriously considered for Python. For one thing, the result is ill-defined unless you control the rounding mode used by HW float division (4.0 / 0.4 == 10.0 only if the rounding mode is to-nearest/even or to-plus-infinity; it's 1 ULP less if to-minus-infinity or to-zero; then taking the floor gives 10 in the former cases but 9 in the latter). It makes scant sense for the result of // to depend on rounding mode: the very name - "floor division" - implies rounding is forced. More fundamentally,
a = (a // b)*b + (a % b)
is the invariant Guido was most keen to preserve. In any conforming C implementation (by the standard today, but by best practice at the time), fmod(4.0, 0.4) == 0.3999999999999998 on a box with 754 doubles, and Python had no interest in building its own idea of "mod" entirely from scratch. Given that, 4 // 0.4 has to return 9.
That said, C's fmod makes more sense for floats than Python's % (which latter makes more sense for integers than C's integer %), because fmod is always exact. Python's float % cannot be, because it retains the sign of the modulus: in, e.g., 1 % -1e100, there is no mathematical integer `n` such that the mathematical 1 + n*-1e100 is both negative and representable as a float.
>>> 1 % -1e100
-1e+100 # negative, but not exactly 1 + 1*-1e100
>>> math.fmod(1, -1e100)
1.0 # is exactly 1 + 0*-1e100, but not negative
In any case, none of this is going to change after 30 years ;-) For Python 3 I had thought Guido agreed to change a % b for floats to return an exact result (exactly equal to the mathematical a - q*b for some mathematical integer q) such that abs(a % b) <= abs(b)/2, which is most useful most often for floats. But that didn't happen. |
|
Date |
User |
Action |
Args |
2019-02-19 03:53:33 | tim.peters | set | recipients:
+ tim.peters, rhettinger, mark.dickinson, steven.daprano, skrah, remi.lapeyre, Au Vo |
2019-02-19 03:53:33 | tim.peters | set | messageid: <1550548413.95.0.748950141296.issue36028@roundup.psfhosted.org> |
2019-02-19 03:53:33 | tim.peters | link | issue36028 messages |
2019-02-19 03:53:33 | tim.peters | create | |
|