Перевод десятичной дроби в обыкновенную

Задачи и их решение / Перевод десятичной дроби в обыкновенную

Онлайн перевод десятичной дроби в обыкновенную

Введите дробь:

Рассмотрим задачу перевода десятичной дроби в обыкновенную с требуемой точностью. Например,
0,3333333 = 1/3
Предполагается, что введенная десятичная дробь не имеет целой части.
Для решения задачи воспользуемся двумя переменными, представляющими собой числитель и знаменатель дроби.
Поиск решения будет состоять из двух этапов:

  • Поиск приближенного решения
  • Уточнение решения до получения требуемой точности

На первом этапе принимаем начальные значения числителя и знаменателя равными 1. На каждом шаге увеличиваем на 1 значение знаменателя и находим дробь
Числитель / Знаменатель
При первой итерации знаменатель равен 1, и 1/1=1, и это значение больше введенной десятичной дроби. Увеличиваем знаменатель на 1 до тех пор пока не получим
Числитель / Знаменатель - ВведеннаяДробь < 0
Таким образом, мы нашли первое приближение. Мы знаем, что введенная дробь соответствует обыкновенной дроби между
Числитель / (Знаменатель - 1) и Числитель / Знаменатель

На втором этапе умножим числитель и знаменатель полученного первого приближения на множитель, который будет принимать последовательно значения 2, 3, 4 и т.д
Снова, увеличивая знаменатель на 1, получим следующее приближение, и если оно устроит нас по точности, то будем считать, что найдена искомая обыкновенная дробь.

Реализация

#include <iostream>
using namespace std;
void func(double num, double eps, int &ch, int &zn) {
  int a = 1; int b = 1;
  int mn = 2; // множитель для начального приближения
  int iter = 0;
  ch = a; zn = b;
  // Поиск начального приближения
  double c = 1;
  do {
    b++;
    c = (double)a / b;
  } while ((num - c) < 0);
  if ((num - c) < eps) {
    ch = a; zn = b;
    return;
  }
  b--;
  c = (double)a / b;
  if ((num - c) > -eps) {
    ch = a; zn = b;
    return;
  }
  // Уточнение
  while (iter < 20000) {
    int cc = a*mn, zz = b*mn;
    iter++;
    do {
      zz++;
      c = (double)cc / zz;
    } while ((num - c) < 0);
    if ((num - c) < eps) {
      ch = cc; zn = zz;
      return;
    }
    zz--;
    c = (double)cc / zz;
    if ((num - c) > -eps) {
      ch = cc; zn = zz;
      return;
    }
    mn++;
}
}
int main() {
  double inp;
  int ch, zn;
  double eps = 0.0000001;
  cout << "num=";
  cin >> inp;
  func(inp, eps, ch, zn);
  cout << ch << " / " << zn << endl;
  cin.get(); cin.get();
  return 1;
}

Результат выполнения
2016-05-13_21-59-01
2016-05-13_22-00-07
2016-05-13_22-00-52

Назад


Назад: Задачи и их решение

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *