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

Feb 5th, 2013
367
0
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. }