# rational.cpp

May 25th, 2022
494
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. #include "rational.h"
2. #include <assert.h>
3.
4. using namespace std;
5.
6. long long gcd(long long a, long long b)
7. {
8.     if (a == 0)
9.         return (b > 0) ? b : -b;
10.     return gcd(b % a, a);
11. }
12.
13. long long lcm(long long a, long long b)
14. {
15.     return (a * b) / gcd(a, b);
16. }
17.
18. Rational::Rational(long long numerator, long long denominator) : _integer(0),
19.                                                                  _numerator(denominator > 0 ? numerator : -numerator),
20.                                                                  _denominator(denominator ? (denominator > 0 ? denominator : -denominator) : 1)
21. {
22.     assert(denominator != 0);
23.     this->simplify();
24. }
25.
26. Rational::Rational(const Rational &temp, bool invert) : _integer(0),
27.                                                         _numerator(invert ? temp._denominator : temp._numerator),
28.                                                         _denominator(invert ? temp._numerator : temp._denominator)
29. {
30.     this->simplify();
31. }
32.
33. Rational &Rational::set(long long numerator, long long denominator)
34. {
35.     _numerator = denominator > 0 ? numerator : -numerator;
36.     _denominator = denominator ? (denominator > 0 ? denominator : -denominator) : 1;
37.     return this->simplify();
38. }
39.
40. long long &Rational::numerator()
41. {
42.     return _numerator;
43. }
44.
45. long long &Rational::denominator()
46. {
47.     return _denominator;
48. }
49.
50. long long &Rational::integer()
51. {
52.     return _integer;
53. }
54.
55. double Rational::get_value()
56. {
57.     return (double)_numerator / (double)_denominator;
58. }
59.
60. Rational &Rational::simplify()
61. {
62.     long long factor = gcd(_numerator, _denominator);
63.     if (_denominator < 0)
64.         factor *= -1;
65.     if (factor != 1)
66.     {
67.         _numerator /= factor;
68.         _denominator /= factor;
69.     }
70.     normalize();
71.     return *this;
72. }
73.
74. Rational &Rational::normalize()
75. {
76.     if (!_integer) _integer = _numerator / _denominator;
77.     _numerator %= _denominator;
78.     // if (_integer && _numerator < 0) _numerator *= -1;
79.     return *this;
80. }
81.
82. Rational &Rational::denormalize()
83. {
84.     // if (_integer < 0 && _numerator > 0) _numerator *= -1;
85.     _numerator += _integer * _denominator;
86.     _integer = 0;
87.     return *this;
88. }
89.
90. istream &operator>>(istream &in, Rational &temp)
91. {
92.     long long num, denom;
93.     in >> num;
94.     in >> denom;
95.     temp.set(num, denom);
96.     return in;
97. }
98.
99. ostream &operator<<(ostream &out, const Rational &r)
100. {
101.     long long num = r._numerator;
102.     if (r._integer) {
103.         out << r._integer;
104.         if (num) {
105.             if (r._integer > 0) out << "+";
106.             if (r._integer < 0) out << "-";
107.             if (num < 0) num *= -1;
108.         }
109.     }
110.     if (r._numerator) {
111.         out << "(" << num;
112.         if (r._denominator != 1) out  << "/" << r._denominator;
113.         out << ")";
114.     } else out << 0;
115.     return out;
116. }
117.
118. Rational &Rational::operator=(const Rational &temp)
119. {
120.     // if (this == &temp) return *this;
121.     // (бесполезно когда нет динамической памяти)
122.     _numerator = temp._numerator;
123.     _denominator = temp._denominator;
124.     return *this;
125. }
126.
127. Rational &Rational::operator=(const long long &temp)
128. {
129.     _numerator = temp;
130.     _denominator = 1;
131.     return *this;
132. }
133.
134. bool operator==(const Rational &r1, const Rational &r2)
135. {
136.     return (r1._integer == r2._integer &&
137.             r1._numerator == r2._numerator &&
138.             r1._denominator == r2._denominator);
139. }
140.
141. bool operator!=(const Rational &r1, const Rational &r2)
142. {
143.     return !(r1 == r2);
144. }
145.
146. const Rational Rational::operator+()
147. {
148.     return Rational(_numerator + _integer * _denominator, _denominator);
149. }
150.
151. const Rational Rational::operator-()
152. {
153.     return Rational(-(_numerator + _integer * _denominator), _denominator);
154. }
155.
156. Rational &Rational::operator++()
157. {
158.     _numerator += _denominator;
159.     return *this;
160. };
161.
162. Rational &Rational::operator--()
163. {
164.     _numerator -= _denominator;
165.     return *this;
166. };
167.
168. Rational Rational::operator++(int)
169. {
170.     Rational temp(*this);
171.     ++(*this);
172.     return temp;
173. };
174.
175. Rational Rational::operator--(int)
176. {
177.     Rational temp(*this);
178.     --(*this);
179.     return temp;
180. };
181.
182. // + - * /
183.
184. Rational operator+(const Rational &r1, const Rational &r2)
185. {
186.     Rational temp(
187.         (r1._numerator + r1._integer * r1._denominator) * r2._denominator +
188.             (r2._numerator + r2._integer * r2._denominator) * r1._denominator,
189.         r1._denominator * r2._denominator);
190.     return temp.simplify();
191. };
192.
193. Rational operator+(const Rational &r, long long value)
194. {
195.     Rational temp(value);
196.     return temp + r;
197. };
198.
199. Rational operator+(long long value, const Rational &r)
200. {
201.     return r + value;
202. };
203.
204. Rational operator-(const Rational &r1, const Rational &r2)
205. {
206.     Rational temp(-r2._numerator, r2._denominator);
207.     return r1 + temp;
208. };
209.
210. Rational operator-(const Rational &r, long long value)
211. {
212.     Rational temp(value);
213.     return r - temp;
214. };
215.
216. Rational operator-(long long value, const Rational &r)
217. {
218.     Rational temp(value);
219.     return temp - r;
220. };
221.
222. Rational operator*(const Rational &r1, const Rational &r2)
223. {
224.     Rational temp(
225.         (r1._numerator + r1._integer * r2._denominator) * (r2._numerator + r2._integer + r2._denominator),
226.         r1._denominator * r2._denominator);
227.     return temp.simplify();
228. };
229.
230. Rational operator*(const Rational &r, long long value)
231. {
232.     Rational temp(value);
233.     return r * temp;
234. };
235.
236. Rational operator*(long long value, const Rational &r)
237. {
238.     return r * value;
239. };
240.
241. Rational operator/(const Rational &r1, const Rational &r2)
242. {
243.     Rational temp(r2, INVERSE); // обратная дробь
244.     return r1 * temp;
245. };
246.
247. Rational operator/(const Rational &r, long long value)
248. {
249.     Rational temp(value);
250.     return r / temp;
251. };
252.
253. Rational operator/(long long value, const Rational &r)
254. {
255.     Rational temp(value);
256.     return temp / r;
257. };
258.
259. // += -= *= /=
260.
261. Rational &operator+=(Rational &left, const Rational &right)
262. {
263.     left = left + right;
264.     return left;
265. };
266.
267. Rational &operator+=(Rational &left, const long long &right)
268. {
269.     left = left + right;
270.     return left;
271. };
272.
273. Rational &operator-=(Rational &left, const Rational &right)
274. {
275.     left = left - right;
276.     return left;
277. };
278.
279. Rational &operator-=(Rational &left, const long long &right)
280. {
281.     left = left - right;
282.     return left;
283. };
284.
285. Rational &operator*=(Rational &left, const Rational &right)
286. {
287.     left = left * right;
288.     return left;
289. };
290.
291. Rational &operator*=(Rational &left, const long long &right)
292. {
293.     left = left * right;
294.     return left;
295. };
296.
297. Rational &operator/=(Rational &left, const Rational &right)
298. {
299.     left = left / right;
300.     return left;
301. };
302.
303. Rational &operator/=(Rational &left, const long long &right)
304. {
305.     left = left / right;
306.     return left;
307. };
308.
309. // < <= > >=
310.
311. bool operator>(const Rational &r1, const Rational &r2)
312. {
313.     long long L = lcm(r1._denominator, r2._denominator);
314.     return (
315.         (r1._numerator + r1._integer * r1._denominator) * L / r1._denominator >
316.         (r2._numerator + r1._integer * r1._denominator) * L / r2._denominator);
317. };
318.
319. bool operator<=(const Rational &r1, const Rational &r2)
320. {
321.     return (r1 == r2 || r1 < r2);
322. };
323.
324. bool operator<(const Rational &r1, const Rational &r2)
325. {
326.     return r2 > r1;
327. };
328.
329. bool operator>=(const Rational &r1, const Rational &r2)
330. {
331.     return (r1 == r2 || r1 > r2);
332. };
333.
334. // сортировка Шелла
335.
336. void ShellSort(int n, Rational* mass[])
337. {
338.     int i, j, step;
339.     Rational* tmp;
340.     for (step = n / 2; step > 0; step /= 2)
341.         for (i = step; i < n; i++)
342.         {
343.             tmp = mass[i];
344.             for (j = i; j >= step; j -= step)
345.             {
346.                 if (*tmp < *mass[j - step])
347.                     mass[j] = mass[j - step];
348.                 else
349.                     break;
350.             }
351.             mass[j] = tmp;
352.         }
353. }