def _o_addsub(self, other, builder, sub, invert=False): if isinstance(other, VFloat): a = self.o_getattr("numerator", builder) b = self.o_getattr("denominator", builder) if sub: if invert: return operators.truediv( operators.sub(operators.mul(other, b, builder), a, builder), b, builder) else: return operators.truediv( operators.sub(a, operators.mul(other, b, builder), builder), b, builder) else: return operators.truediv( operators.add(operators.mul(other, b, builder), a, builder), b, builder) else: if not isinstance(other, (VFraction, VInt)): return NotImplemented r = VFraction() if builder is not None: if isinstance(other, VInt): i = other.o_int64(builder).auto_load(builder) x, rd = self._nd(builder) y = builder.mul(rd, i) else: a, b = self._nd(builder) c, d = other._nd(builder) rd = builder.mul(b, d) x = builder.mul(a, d) y = builder.mul(c, b) if sub: if invert: rn = builder.sub(y, x) else: rn = builder.sub(x, y) else: rn = builder.add(x, y) rn, rd = _reduce(builder, rn, rd) # rd is already > 0 r.auto_store(builder, _make_ssa(builder, rn, rd)) return r
def _o_muldiv(self, other, builder, div, invert=False): if isinstance(other, VFloat): a = self.o_getattr("numerator", builder) b = self.o_getattr("denominator", builder) if invert: a, b = b, a if div: return operators.truediv(a, operators.mul(b, other, builder), builder) else: return operators.truediv(operators.mul(a, other, builder), b, builder) else: if not isinstance(other, (VFraction, VInt)): return NotImplemented r = VFraction() if builder is not None: a, b = self._nd(builder) if invert: a, b = b, a if isinstance(other, VInt): i = other.o_int64(builder).auto_load(builder) if div: b = builder.mul(b, i) else: a = builder.mul(a, i) else: c, d = other._nd(builder) if div: a = builder.mul(a, d) b = builder.mul(b, c) else: a = builder.mul(a, c) b = builder.mul(b, d) if div or invert: a, b = _signnum(builder, a, b) a, b = _reduce(builder, a, b) r.auto_store(builder, _make_ssa(builder, a, b)) return r