Когда в задаче много раз выполняются действия с дробными числами, то точность вычислений может потеряться, поэтому приходится писать свою структуру для работы с дробями. Поделюсь своим опытом и надеюсь чем-нибудь помогу) Ниже я привёл код, которым я сам пользуюсь, теперь расскажу как он устроен и что умеет:
- чтобы пользоваться структурой нужно использовать
#include <iostream>
#include <numeric>
#include <string>
using namespace std;
структура называется
Fraction
и в ней хранится числитель и знаменатель (поля с названиямиa
иb
соответственно, их типlong long
), если вручную не изменять поля, то будет поддерживаться:- положительный знаменатель, а значит знак числителя это знак всей дроби
- числитель и знаменатель взаимнопросты
- строки вида "1234/5678" и "1234:5678" структура считает похожими на дробь, до
/
или:
числитель, а после — знаменатель, а строки вида "1234" структура считает похожими на целое число, строки вида "1234.5678" структура считает похожими на десятичную дробь.
- по умолчанию
a = 0, b = 1
, также определены конструкторы, поэтомуFraction(x)
устанавливаетa = x, b = 1
, аFraction(x, y)
устанавливаетa = x, b = y
при этомx
иy
должны быть целыми числами. Если нужно получить дробь из строки или double то стоит воспользоваться функциейtof()
- для дробей(структуры Fraction) переопределены операторы
+= -= *= /= + - * / < > <= >= == !=
, также эти операторы можно использовать с целыми числами, но если вы хотите использовать их сdouble
, то нужно будет предварительно перевестиdouble
вFraction
с помощьюtof()
.
- конечно переопределены операторы ввода(если считаная строка будет похожа на дробь или десятичную дробь, то ввод закончится, в противном случае он будет думать что ввёл числитель и считает знаменатель) и вывода(выводится десятичная дробь. если хочется вывести в виде обыкновенной дроби, то стоит воспользоваться оператором
()
например еслиFraction f(1, 2)
тоcout<<f();
выведет1/2
)
- перегружен оператор
()
который принимает строку-разделитель(по умолчанию она равна "/") и возвращает строку, поэтому если естьFraction f
, тоf(":")
вернёт "0:1"(возвращается строка состоящая из числителя + строки-разделителя + знаменателя)
- для взятия дроби по модулю, обратного числа или максимума/минимума из двух дробей можно использовать функции
abs() rev() max() min()
, также есть методыabs()
иrev()
которые делают дробь положительной или меняют числитель и знаменатель местами соответственно. При использованииrev
знаменатель не должен быть равен 0.
- функциям
tol()
иtod()
необходимо передатьFraction
и вернут они соответственноlong long
(целую часть у дроби) иlong double
(десятичную дробь), функцияtodd()
принимаетFraction
и возвращаетFraction
(дробную часть числа)
- функция
tof()
принимаетstring
илиdouble
возвращаетFraction
если была передана строка то результат будет зависеть от того похожа ли строка на целое число, дробь или десятичную дробь. Помимо этого можно передать два значения(tof(x, y)
) первоеdouble
илиstring
и второеdouble
илиstring
тогда вернётся дробь равнаяtof(x)/tof(y)
А вот и сам код