NickAndNick

Простой калькулятор рациональных чисел

Feb 5th, 2013
164
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <conio.h>
  3. #include <string>
  4.  
  5. using namespace std;
  6.  
  7. enum choice {
  8.     ESC      = 27,
  9.     INCREASE = 42,
  10.     COMBINE  = 43,
  11.     SUBTRACT = 45,    
  12.     DIVIDE   = 47
  13. };
  14.  
  15. struct rational {
  16.     int numerator;
  17.     int denominator;
  18. };
  19. typedef rational RATIONAL;
  20.  
  21. void combine(const RATIONAL, const RATIONAL);
  22. void subtract(const RATIONAL, const RATIONAL);
  23. void increase(const RATIONAL, const RATIONAL);
  24. void divide(const RATIONAL, const RATIONAL);
  25. int  nod(int, int);
  26. void reduce(RATIONAL &);
  27. void show(const RATIONAL, const RATIONAL, const RATIONAL, const string);
  28. int  validint(const RATIONAL, const RATIONAL);
  29. char validchar();
  30. void err();
  31. void zero();
  32. void ui();
  33. void ru();
  34.  
  35. int main() {
  36.     ru();
  37.     ui();
  38.     return 0;
  39. }
  40.  
  41. void reduce(RATIONAL & _rat) {
  42.     int n = nod(_rat.numerator, _rat.denominator);
  43.  
  44.     if (n) {
  45.         _rat.numerator /= n;
  46.         _rat.denominator /= n;
  47.     }
  48. }
  49.  
  50. int nod(int _a, int _b) {
  51.     int a = abs(_a);
  52.     int b = abs(_b);
  53.  
  54.     if (!a && !b) a = 0;
  55.     else while (b) b ^= a ^= b ^= a %= b;
  56.  
  57.     return a;
  58. }
  59.  
  60. void combine(const RATIONAL _first, const RATIONAL _second) {
  61.     RATIONAL result;
  62.     result.numerator   = _first.numerator * _second.denominator + _second.numerator * _first.denominator;
  63.     result.denominator = _second.denominator * _first.denominator;
  64.     reduce(result);
  65.     if (result.denominator) show(_first, _second, result, " + ");
  66.     else zero();
  67. }
  68.  
  69. void subtract(const RATIONAL _first, const RATIONAL _second) {
  70.     RATIONAL result;
  71.     result.numerator   = _first.numerator * _second.denominator - _second.numerator * _first.denominator;
  72.     result.denominator = _second.denominator * _first.denominator;
  73.     reduce(result);
  74.     if (result.denominator) show(_first, _second, result, " - ");
  75.     else zero();
  76. }
  77.  
  78. void increase(const RATIONAL _first, const RATIONAL _second) {
  79.     RATIONAL result;
  80.     result.numerator   = _first.numerator * _second.numerator;
  81.     result.denominator = _first.denominator * _second.denominator;
  82.     reduce(result);
  83.     if (result.denominator) show(_first, _second, result, " * ");
  84.     else zero();
  85. }
  86.  
  87. void divide(const RATIONAL _first, const RATIONAL _second) {
  88.     RATIONAL result;
  89.     result.numerator   = _first.numerator * _second.denominator;
  90.     result.denominator = _first.denominator * _second.numerator;
  91.     reduce(result);
  92.     if (result.denominator) show(_first, _second, result, " / ");
  93.     else zero();
  94. }
  95. void zero() { wcout << L"Ошибка! Попытка деления на ноль\n\a"; }
  96.  
  97. void show(const RATIONAL _first, const RATIONAL _second, const RATIONAL _result, const string _op) {
  98.     cout << _first.numerator  << '/' << _first.denominator  << _op
  99.          << _second.numerator << '/' << _second.denominator << " = ";
  100.     if ((_op == " * " && (!_first.numerator || !_second.numerator)) || !_first.numerator && !_second.numerator) cout << 0;
  101.     else cout << _result.numerator << '/' << _result.denominator;
  102.     cout << endl;
  103. }
  104.  
  105. char validchar() {
  106.     do {
  107.         fflush(stdin);
  108.         char op = cin.get();
  109.  
  110.         if (op == INCREASE || op == COMBINE || op == SUBTRACT || op == DIVIDE) return op;
  111.         else err();
  112.     } while (true);
  113. }
  114.  
  115. int validint() {
  116.     int num;
  117.  
  118.     do {        
  119.         cin >> num;
  120.         if (cin.good()) return num;
  121.         else err();
  122.     } while (true);
  123. }
  124.  
  125. void err() {
  126.     cin.clear();
  127.     cin.ignore(80,'\n');
  128.     wcout << L"\a Ошибка! Повторите попытку:       ";
  129. }
  130.  
  131. void ui() {    
  132.     RATIONAL first, second;
  133.  
  134.     do {        
  135.         wcout << L"\nВведите числитель первой дроби:  ";
  136.         first.numerator = validint();
  137.         wcout << L"Введите знаменатель первой дроби: ";
  138.         first.denominator = validint();
  139.         wcout << L"Введите арифметическую операцию:  ";
  140.         char choice = validchar();
  141.         wcout << L"Введите числитель второй дроби:  ";
  142.         second.numerator = validint();
  143.         wcout << L"Введите знаменатель второй дроби: ";
  144.         second.denominator = validint();
  145.  
  146.         switch (choice) {
  147.             case COMBINE:  combine(first, second);  break;
  148.             case SUBTRACT: subtract(first, second); break;
  149.             case INCREASE: increase(first, second); break;
  150.             case DIVIDE:   divide(first, second);   break;
  151.         }
  152.  
  153.         wcout << L"\nДля выхода нажмите клавишу ESC\nДля продолжения любую другую клавишу";
  154.         fflush(stdin);
  155.         if (ESC == _getch()) break;
  156.         else cout << endl;
  157.     } while (true);
  158. }
  159.  
  160. void ru() {
  161.     wcout.imbue(locale(".866"));
  162.     wcin.imbue(locale(".866"));
  163. }
RAW Paste Data