#include #include #include #include #include #define abs(x) ((x) < 0 ? -(x) : (x)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) bool isnan(double value) { return value != value; } template class Fraction { private: T numerator; T denominator; T gcd(T a, T b) const { while (b != 0) { T temp = b; b = a % b; a = temp; } return abs(a); } T lcm(T a, T b) const { return (a / gcd(a, b)) * b; } void simplify() { if (denominator == 0) { numerator = std::numeric_limits::max(); denominator = 1; return; } if (numerator == 0) { denominator = 1; return; } if (denominator < 0) { numerator = -numerator; denominator = -denominator; } T common = gcd(abs(numerator), denominator); numerator /= common; denominator /= common; } public: Fraction(T num, T den) : numerator(num), denominator(den) { simplify(); } Fraction(const Fraction& other) : numerator(other.numerator), denominator(other.denominator) {} //Copy Fraction(Fraction&& other) noexcept : numerator(std::move(other.numerator)), denominator(std::move(other.denominator)) {} //Move explicit Fraction(double value) { if (isnan(value)) { numerator = std::numeric_limits::max(); denominator = 1; } else { const T precision = std::numeric_limits::max() / 10; numerator = static_cast(value * precision); denominator = precision; simplify(); } } explicit Fraction() { Fraction(0, 1); } T getNumerator() const { return numerator; } void setNumerator(T num) { numerator = num; simplify(); } T getDenominator() const { return denominator; } void setDenominator(T den) { denominator = den; simplify(); } bool isNegative() const { return numerator < 0; } double toDouble() const { return static_cast(numerator) / denominator; } Fraction operator-() const { return Fraction(-numerator, denominator); } template Fraction::type> operator+(const Fraction& other) const { using ResultType = typename std::common_type::type; ResultType commonDenominator = lcm(denominator, other.getDenominator()); ResultType num1 = numerator * (commonDenominator / denominator); ResultType num2 = other.getNumerator() * (commonDenominator / other.getDenominator()); return Fraction(num1 + num2, commonDenominator); } template Fraction::type> operator-(const Fraction& other) const { return *this + -other; } template Fraction::type> operator*(const Fraction& other) const { using ResultType = typename std::common_type::type; return Fraction(numerator * other.getNumerator(), denominator * other.getDenominator()); } template Fraction::type> operator/(const Fraction& other) const { using ResultType = typename std::common_type::type; if (other.getNumerator() == 0) { return Fraction(std::numeric_limits::max(), 1); } return Fraction(numerator * other.getDenominator(), denominator * abs(other.getNumerator())); } template Fraction::type> pow(U exponent) const { using ResultType = typename std::common_type::type; if (exponent == 0) { return Fraction(1, 1); } bool negativeExponent = (exponent < 0); exponent = abs(exponent); ResultType num = 1; ResultType den = 1; for (U i = 0; i < exponent; ++i) { num *= numerator; den *= denominator; } if (negativeExponent) { std::swap(num, den); } return Fraction(num, den); } template bool operator==(const Fraction& other) const { return 0; //TODO: 0 durch einen korrekten Ausdruck ersetzen } template bool operator<(const Fraction& other) const { return 0; //TODO: 0 durch korrekten Ausdruck ersetzen. } template bool operator<=(const Fraction& other) const { return 0; //TODO: 0 durch korrekten Ausdruck ersetzen. Boolesche Operatoren benutzen. } template bool operator>(const Fraction& other) const { return 0; //TODO: 0 durch korrekten Ausdruck ersetzen. } template bool operator>=(const Fraction& other) const { return 0; //TODO: 0 durch korrekten Ausdruck ersetzen. } template bool operator!=(const Fraction& other) const { return 0; //TODO: 0 durch korrekten Ausdruck ersetzen. } Fraction& operator=(const Fraction& other) { //Copy if (this != &other) { numerator = other.numerator; denominator = other.denominator; } return *this; } Fraction& operator=(Fraction&& other) noexcept { //Move if (this != &other) { numerator = std::move(other.numerator); denominator = std::move(other.denominator); } return *this; } Fraction& operator=(double value) { *this = Fraction(value); return *this; } Fraction& operator=(T value) { numerator = value; denominator = 1; return *this; } template Fraction& operator=(U value) { numerator = static_cast(value); denominator = 1; return *this; } template Fraction& operator=(const Fraction& other) { numerator = static_cast(other.getNumerator()); denominator = static_cast(other.getDenominator()); simplify(); return *this; } friend std::ostream& operator<<(std::ostream& os, const Fraction& frac) { if (frac.getDenominator() == 1) { os << frac.getNumerator(); } else { os << frac.getNumerator() << "/" << frac.getDenominator(); } return os; } }; template Fraction::type> operator+(const Fraction& frac, U value) { return frac + Fraction(value, 1); } template Fraction::type> operator+(U value, const Fraction& frac) { return Fraction(value, 1) + frac; } template Fraction::type> operator-(const Fraction& frac, U value) { return frac - Fraction(value, 1); } template Fraction::type> operator-(U value, const Fraction& frac) { return Fraction(value, 1) - frac; } template Fraction::type> operator*(const Fraction& frac, U value) { return frac * Fraction(value, 1); } template Fraction::type> operator*(U value, const Fraction& frac) { return Fraction(value, 1) * frac; } template Fraction::type> operator/(const Fraction& frac, U value) { return frac / Fraction(value, 1); } template Fraction::type> operator/(U value, const Fraction& frac) { return Fraction(value, 1) / frac; } template bool operator<(const Fraction& frac, U value) { return frac < Fraction(value, 1); } template bool operator<=(const Fraction& frac, U value) { return frac <= Fraction(value, 1); } template bool operator>(const Fraction& frac, U value) { return frac > Fraction(value, 1); } template bool operator>=(const Fraction& frac, U value) { return frac >= Fraction(value, 1); } template bool operator==(const Fraction& frac, U value) { return frac == Fraction(value, 1); } template bool operator!=(const Fraction& frac, U value) { return frac != Fraction(value, 1); } namespace std { template struct hash> { std::size_t operator()(const Fraction& frac) const { return std::hash()(frac.getNumerator()) ^ std::hash()(frac.getDenominator()); } }; } using fraction = Fraction; int main(int argc, char* argv[]) { int a = 1, b = 2, c = 3, d = 4; if (argc == 5) { try { a = std::stoi(argv[1]); b = std::stoi(argv[2]); c = std::stoi(argv[3]); d = std::stoi(argv[4]); } catch (...) { } } Fraction frac0(c, d); Fraction frac1(a, b); Fraction frac2(d, c); Fraction frac3(a, c); int z = 7; frac2 = frac0; frac3 = frac1; std::cout << frac1 << ", " << frac2 << ", " << frac3 << ", " << Fraction(z, 1) << std::endl; auto sum = frac1 + frac2; auto diff = frac1 - frac2; auto prod = frac1 * frac2; auto quot = frac1 / frac2; std::cout << sum << ", " << diff << ", " << prod << ", " << quot << " | "; auto sum2 = frac1 + z; auto diff2 = frac1 - z; auto prod2 = frac1 * z; auto quot2 = frac1 / z; std::cout << sum2 << ", " << diff2 << ", " << prod2 << ", " << quot2 << std::endl; std::cout << frac1.pow(2) << ", " << frac1.pow(-2) << std::endl; std::cout << (frac1 != frac2) << ", " << (frac1 < frac2) << ", " << (frac1 <= frac2) << ", " << (frac1 == frac2) << ", " << (frac1 >= frac2) << ", " << (frac1 > frac2) << ", " << std::endl; std::cout << (frac1 != frac3) << ", " << (frac1 < frac3) << ", " << (frac1 <= frac3) << ", " << (frac1 == frac3) << ", " << (frac1 >= frac3) << ", " << (frac1 > frac3) << ", " << std::endl; std::cout << (frac1 != z) << ", " << (frac1 < z) << ", " << (frac1 <= z) << ", " << (frac1 == z) << ", " << (frac1 >= z) << ", " << (frac1 > z) << ", " << std::endl; Fraction frac4(1, 3); frac4 = 0.5; std::cout << frac4 << std::endl; Fraction frac5(2, 5); long int frac5nominator = -2; frac5 = frac5nominator; std::cout << frac5 << std::endl; fraction frac6; frac6 = 0.25; std::cout << frac6 << std::endl; std::unordered_map, std::string> fractionMap; fractionMap[Fraction(1, 2)] = "Half"; std::cout << fractionMap[Fraction(1, 2)] << std::endl; return 0; }