Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <sstream>
- using namespace std;
- class Fraction {
- public:
- using inner_type = long long;
- Fraction() : val({ 0, 1 }) {}
- Fraction(const string& str) {
- val = split(str, '/');
- normalize();
- }
- string value()const {
- return to_string(val.first) + '/' + to_string(val.second);
- }
- Fraction absolute()const {
- return Fraction(abs(val.first), val.second);
- }
- Fraction& operator-() {
- val.first *= -1;
- return *this;
- }
- bool corrupt()const {
- return val.second == 0;
- }
- private:
- pair<inner_type, inner_type> val;
- Fraction(inner_type a, inner_type b) : val{ a, b } {
- normalize();
- }
- void normalize() {
- auto x = gcd(val);
- if (x) {
- val.first /= x;
- val.second /= x;
- if (val.second < 0) {
- val.first *= -1;
- val.second *= -1;
- }
- }
- }
- inner_type gcd(pair<inner_type, inner_type> v) {
- if (v.second) {
- v.first = abs(v.first);
- if (v.first) {
- v.second = abs(v.second);
- while (v.first != v.second) {
- if (v.first > v.second) swap(v.first, v.second);
- v.second -= v.first;
- }
- }
- }
- return v.first;
- }
- pair<inner_type, inner_type> split(const string& str, char delim) {
- pair<inner_type, inner_type> box;
- stringstream ss(str);
- try {
- string token;
- getline(ss, token, delim);
- box.first = stoll(token);
- getline(ss, token);
- box.second = stoll(token);
- } catch (...) {
- box.second = 0;
- ss.clear();
- ss.ignore(ss.rdbuf()->in_avail());
- }
- return box;
- }
- friend Fraction operator-(const Fraction& a, const Fraction& b) {
- const auto an = a.val.first * b.val.second;
- const auto bn = b.val.first * a.val.second;
- const auto abn = an - bn;
- const auto abd = a.val.second * b.val.second;
- return Fraction(to_string(abn) + '/' + to_string(abd));
- }
- friend bool operator<(const Fraction& a, const Fraction& b) {
- return double(a.val.first) / a.val.second < double(b.val.first) / b.val.second;
- }
- friend bool operator<(const Fraction& a, const double b) {
- return double(a.val.first) / a.val.second < b;
- }
- friend bool operator<(const double a, const Fraction& b) {
- return a < double(b.val.first) / b.val.second;
- }
- friend bool operator==(const Fraction& a, const Fraction& b) {
- return a.val.first == b.val.first && a.val.second == b.val.second;
- }
- friend bool operator==(const Fraction& a, const double b) {
- return double(a.val.first) / a.val.second == b;
- }
- friend bool operator>(const Fraction& a, const Fraction& b) {
- return double(a.val.first) / a.val.second > double(b.val.first) / b.val.second;
- }
- friend bool operator>(const Fraction& a, const double b) {
- return double(a.val.first) / a.val.second > b;
- }
- friend Fraction operator%(const Fraction& a, const Fraction& b) {
- auto xa = a.absolute();
- auto xb = b.absolute();
- if (xa < xb) return a;
- auto x = xa - xb;
- if (x == 0) return Fraction(0, 1);
- while (x > xb) x = x - xb;
- return a.val.first > 0 ? x : -x;
- }
- friend Fraction operator%(const inner_type a, const Fraction& b) {
- Fraction x(a, 1);
- return operator%(x, b);
- }
- friend Fraction operator*(const Fraction& a, const inner_type b) {
- return Fraction(a.val.first * b, a.val.second);
- }
- friend Fraction operator*(const inner_type a, const Fraction& b) {
- return Fraction(b.val.first * a, b.val.second);
- }
- friend Fraction operator*(const Fraction& a, const Fraction& b) {
- return Fraction(a.val.first * b.val.first, a.val.second * b.val.second);
- }
- friend Fraction operator/(const Fraction& a, const Fraction& b) {
- return Fraction(a.val.first * b.val.second, a.val.second * b.val.first);
- }
- friend Fraction operator+(const Fraction& a, const Fraction& b) {
- auto d = a.val.second * b.val.second;
- auto n = a.val.first * b.val.second + b.val.first * a.val.second;
- return Fraction(n, d);
- }
- friend Fraction operator+(const Fraction& a, const inner_type b) {
- auto d = a.val.second;
- auto n = a.val.first + b * a.val.second;
- return Fraction(n, d);
- }
- friend Fraction operator+(const inner_type b, const Fraction& a) {
- auto d = a.val.second;
- auto n = a.val.first + b * a.val.second;
- return Fraction(n, d);
- }
- friend ostream& operator<<(ostream& out, const Fraction& fr) {
- return out << fr.val.first << '/' << fr.val.second;
- }
- friend istream& operator>>(istream& inp, Fraction& fr) {
- string str;
- inp >> str;
- fr.val = fr.split(str, '/');
- fr.normalize();
- return inp;
- }
- };
- Fraction fraction(const string& msg) {
- Fraction value;
- do {
- cout << "Введите " << msg;
- if (!msg.empty()) cout.put(' ');
- cout << "(дробь в формате x/y): ";
- cin >> value;
- cin.ignore(cin.rdbuf()->in_avail());
- } while (value.corrupt());
- return value;
- }
- int main() {
- system("chcp 1251 > nul");
- auto a = fraction("первую");
- auto b = fraction("вторую");
- char operation;
- auto repeat = true;
- do {
- cout << "Введите арифметическую операцию [ + - * / % ]: ";
- operation = cin.get();
- cin.ignore(cin.rdbuf()->in_avail());
- Fraction result;
- switch (operation) {
- case '+': result = a + b; break;
- case '-': result = a - b; break;
- case '/': result = a / b; break;
- case '*': result = a * b; break;
- case '%': result = a % b; break;
- default: repeat = false;
- }
- if (repeat) {
- cout
- << a << ' ' << operation << ' '
- << b << " = " << result << '\n';
- }
- } while (repeat);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement