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

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

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

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

Рассмотрим задачу перевода десятичной дроби в обыкновенную с требуемой точностью.

Например,

0,3333333 = 1/3

Предполагается, что введенная десятичная дробь не имеет целой части.

Для решения задачи воспользуемся двумя переменными, представляющими собой числитель и знаменатель дроби.

Поиск решения будет состоять из двух этапов:

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

На первом этапе принимаем начальные значения числителя и знаменателя равными 1. На каждом шаге увеличиваем на 1 значение знаменателя и находим дробь

Числитель / Знаменатель

При первой итерации знаменатель равен 1

1 / 1 = 1,

и это значение больше введенной десятичной дроби.

Увеличиваем знаменатель на 1 до тех пор, пока не получим

Числитель / Знаменатель — ВведеннаяДробь < 0

Таким образом, мы нашли первое приближение. Мы знаем, что введенная дробь соответствует обыкновенной дроби между

Числитель / (Знаменатель — 1) и Числитель / Знаменатель

На втором этапе умножим числитель и знаменатель полученного первого приближения на множитель, который будет принимать последовательно значения

2, 3, 4 и т.д

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

Реализация на C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#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.00000000001;   
  cout << "num=";   
  cin >> inp;   
  func(inp, eps, ch, zn);   
  cout << ch << " / " << zn << endl;   
  cin.get(); cin.get();   
  return 0; 
}

Результат выполнения

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

2 комментария к “Перевод десятичной дроби в обыкновенную”

  1. Андрей

    Добрый день! При вводе 0.6666 ответ должен быть 3333 / 5000. А выдает 3329 / 4994. Как это можно исправить? Делаю курсовую работу, преподаватель хочет именно чтобы так работала программа. Но как это реализовать?

    1. Елена Вставская

      В формате double, к сожалению, число 0,6666 представляется как 0,66659999999999997. Тут и кроется эта проблема.
      Возможно поможет увеличение точности представления дроби — уменьшение значения eps.

Оставьте комментарий

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

Прокрутить вверх