Raymond Hettinger <[email protected]> added the comment:
I'm thinking this due to having two different algorithms in play, one of which
has multiple intermediate roundings.
* For starters, 0.4 is not exactly representable. It is stored as the binary
fraction 3602879701896397 / 9007199254740992 represented in hex as
0x1.999999999999ap-2
* The / true division operator is implemented in
Objects/floatobject.c:float_div() with a single, straight division of C
doubles: "a = a / b;" That is giving 10.0 when rounded.
* The // floor division operator is implemented in
Objects/floatobject.c:float_floor_div() which in turn calls float_divmod().
The latter has a number of steps that can each have a round-off and can make
adjustments to preserve sign logic invariants:
mod = fmod(vx, wx);
/* fmod is typically exact, so vx-mod is *mathematically* an
exact multiple of wx. But this is fp arithmetic, and fp
vx - mod is an approximation; the result is that div may
not be an exact integral value after the division, although
it will always be very close to one.
*/
div = (vx - mod) / wx;
if (mod) {
/* ensure the remainder has the same sign as the denominator */
if ((wx < 0) != (mod < 0)) {
mod += wx;
div -= 1.0;
}
}
else {
/* the remainder is zero, and in the presence of signed zeroes
fmod returns different results across platforms; ensure
it has the same sign as the denominator. */
mod = copysign(0.0, wx);
}
/* snap quotient to nearest integral value */
if (div) {
floordiv = floor(div);
if (div - floordiv > 0.5)
floordiv += 1.0;
}
else {
/* div is zero - get the same sign as the true quotient */
floordiv = copysign(0.0, vx / wx); /* zero w/ sign of vx/wx */
}
I don't see how to fix the discrepancy without having float_div() depend on the
much slower logic in float_divmod().
----------
nosy: +mark.dickinson, skrah, tim.peters
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue36028>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com