PROG666's blog

By PROG666, 2 days ago, In Russian

Когда в задаче много раз выполняются действия с дробными числами, то точность вычислений может потеряться, поэтому приходится писать свою структуру для работы с дробями. Поделюсь своим опытом и надеюсь чем-нибудь помогу) Ниже я привёл код, которым я сам пользуюсь, теперь расскажу как он устроен и что умеет:

  • чтобы пользоваться структурой нужно использовать #include <iostream> #include <numeric> #include <string> using namespace std;
  • структура называется Fraction и в ней хранится числитель и знаменатель (поля с названиями a и b соответственно, их тип long long), если вручную не изменять поля, то будет поддерживаться:

    1. положительный знаменатель, а значит знак числителя это знак всей дроби
    2. числитель и знаменатель взаимнопросты
  • строки вида "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)
А вот и сам код
  • Vote: I like it
  • 0
  • Vote: I do not like it