2013-04-06 4 views
1

предположив У меня есть десятичное какалгоритм для преобразования десятичных чисел дроби выражение

0.30000000000000027 

Что бы лучший алгоритм, чтобы знать то же самое число выражается в виде дроби Так, при определенных x найти y, что удовлетворяет x=1/y в с или Haskell

Я думал

1/3> 0.30 >1/4 

Итерация влево и правая сторона сезам один из них сходится и > становится = поэтому первая итерация будет выглядеть

1/1 > 0.30000000000000027 > 1/somethinghere 
1/2 > 0.30000000000000027 > 1/increase or decrease this 
1/3 > 0.30000000000000027 ... 

Я хочу уточнить, что я мог бы легко сделать

0.30000000000000027 = 30000000000000027/ 10^17 

, но я хочу сделать

0.30000000000000027 = 1/x 

В c или haskell

+2

Не все числа могут быть выражены, например, 0,8 = 4/5. – Koterpillar

+0

да, но если алгоритм не сходится, то у меня есть номер с этим качеством. – cMinor

+0

Тогда вам просто нужен алгоритм упрощения фракций, см., Например, http://stackoverflow.com/questions/7777142/how-to-simplify- фракция. – Koterpillar

ответ

4

Voila (преобразует почти правильно к нормальным ФВ):

int gcd(int a, int b) 
{ 
    if (a == 0) return b; 
    if (b == 0) return a; 

    if (a > b) 
     return gcd(b, a % b); 
    else 
     return gcd(a, b % a); 
} 

struct frac { 
    int num; 
    int denom; 
}; 

struct frac to_frac(double x, int precision) 
{ 
    int denom = 1; 
    for (int i = 0; i < precision; i++) { 
     denom *= 10; 
    } 

    int num = x * denom + 0.5; // hack: round if imprecise 
    int gcdiv = gcd(num, denom); 

    struct frac f; 
    f.num = num/gcdiv; 
    f.denom = denom/gcdiv; 

    return f; 
} 
+1

Sidenote: это не готовое к производству, а некоторые необходимо, если вы хотите, чтобы он работал при любых обстоятельствах - это осталось как упражнение, этого очень многого кода должно быть достаточно, чтобы начать OP. – 2013-04-06 06:28:23

+0

typedef struct будет лучше читать, я думаю. –

+0

@ Koushik Да, возможно :) – 2013-04-06 06:31:36

2

Не знаю Haskell, здесь в псевдокоде:

raw_denom = 1/x; 
print "1/" floor(raw_denom) " >= " x " >= 1/" ceil(raw_denom) 
+0

'1/1> = 0,8> = 1/2' Все зависит от (нечетких) требований к дизайну, но это соответствует некоторой интерпретации. В Haskell: 'func x = let raw_denom = 1/x в putStrLn $" 1/"++ show (floor raw_denom) ++"> = "++ show x ++"> = 1/"++ show (потолок raw_denom) ' –

+0

Мой ответ печатает то, что он написал после того, как« я думал »в его вопросе. – Barmar