def float_mod(a, b): y = b.number mod = math_fmod(a.number, y) # Follows pypy implementation. if mod: # I'm not sure why remainder and denominator if (y < 0.0) != (mod < 0.0): # must have the same sign. mod += y else: mod = copysign(0.0, y) return Float(mod)
def descr_mod(self, space, w_rhs): w_rhs = self._to_float(space, w_rhs) if w_rhs is None: return space.w_NotImplemented x = self.floatval y = w_rhs.floatval if y == 0.0: raise oefmt(space.w_ZeroDivisionError, "float modulo") mod = math_fmod(x, y) if mod: # ensure the remainder has the same sign as the denominator if (y < 0.0) != (mod < 0.0): mod += y 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; we'd like to do # "mod = y * 0.0", but that may get optimized away mod = copysign(0.0, y) return W_FloatObject(mod)
def _divmod_w(space, w_float1, w_float2): x = w_float1.floatval y = w_float2.floatval if y == 0.0: raise oefmt(space.w_ZeroDivisionError, "float modulo") mod = math_fmod(x, y) # 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 = (x - mod) / y if (mod): # ensure the remainder has the same sign as the denominator if ((y < 0.0) != (mod < 0.0)): mod += y 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; we'd like to do # "mod = wx * 0.0", but that may get optimized away mod *= mod # hide "mod = +0" from optimizer if y < 0.0: mod = -mod # snap quotient to nearest integral value if div: floordiv = math.floor(div) if (div - floordiv > 0.5): floordiv += 1.0 else: # div is zero - get the same sign as the true quotient div *= div # hide "div = +0" from optimizers floordiv = div * x / y # zero w/ sign of vx/wx return [W_FloatObject(floordiv), W_FloatObject(mod)]