Fraction Fraction::operator += (const Fraction& rhs) { const int lcm = LCM(DenominatorAsInt(), rhs.DenominatorAsInt()); int A = 0, B = 0; if (__builtin_mul_overflow(numerator / DenominatorAsInt(), lcm, &A)) goto err; if (__builtin_mul_overflow(rhs.numerator / rhs.DenominatorAsInt(), lcm, &B)) goto err; if (__builtin_add_overflow(A, B, &numerator)) goto err; denominator = lcm; Reduce(); return *this; err: valid = false; return *this; }
Fraction Fraction::operator *= (const Fraction& rhs) { if (__builtin_mul_overflow(numerator, rhs.numerator, &numerator)) goto err; if (__builtin_mul_overflow(DenominatorAsInt(), rhs.DenominatorAsInt(), &denominator)) goto err; Reduce(); return *this; err: valid = false; return *this; }
Fraction Fraction::operator -= (const Fraction& rhs) { const int lcm = LCM(DenominatorAsInt(), rhs.DenominatorAsInt()); int A = 0, B = 0; if (__builtin_mul_overflow(numerator / DenominatorAsInt(), lcm, &A)) goto err; if (__builtin_mul_overflow(rhs.numerator / rhs.DenominatorAsInt(), lcm, &B)) goto err; if (__builtin_sub_overflow(A, B, &numerator)) goto err; denominator = lcm; Reduce(); // std::cout << "result: " << *this << std::endl; return *this; err: valid = false; return *this; }
Fraction Fraction::operator / (const Fraction& rhs) const { int newNumerator = Numerator() * rhs.DenominatorAsInt(); int newDenominator = DenominatorAsInt() * rhs.Numerator(); return Fraction(0, newNumerator, newDenominator); }
Fraction Fraction::operator - (const Fraction& rhs) const { const int lcm = LCM(DenominatorAsInt(), rhs.DenominatorAsInt()); int result = (numerator * lcm / DenominatorAsInt()) - (rhs.numerator * lcm / rhs.DenominatorAsInt()); return Fraction(0, result, lcm); }