2014-10-30 4 views
1

Что такое алгоритм, который я могу использовать для преобразования и ввода десятичного числа во фракционную форму в C++. Например, если я вхожу в 1.25, я бы хотел, чтобы преобразование в результат было 1 1/4.Преобразование десятичного числа в дробь C++

+2

Что вы написали до сих пор и как вы хотите, чтобы фракция была выведена? –

+0

Одна идея, просто идея, выяснить способ найти 2 фракции, один меньше, чем ответ, другой больше. Затем оттуда, петля по направлению друг к другу и найти ближайший, если только не будет целого числа. –

+0

Под «десятичным», вы имеете в виду, что ваш ввод представляет собой строку десятичных цифр и десятичную точку, или вы просто имеете в виду не целое число? Обратите внимание, что как десятичные числа, так и двоичные числа с плавающей запятой фактически представляют собой представления фракций, но не обязательно ту долю, о которой вы думали. Например, представление доли 1/3 в двоичном или десятичном значении фактически представляет собой другое число. –

ответ

6

Сначала получите дробную часть, а затем возьмите gcd. Используйте алгоритм Евклида http://en.wikipedia.org/wiki/Euclidean_algorithm

void foo(double input) 
{ 
    double integral = std::floor(input); 
    double frac = input - integral; 

    const long precision = 1000000000; // This is the accuracy. 

    long gcd_ = gcd(round(frac * precision), precision); 

    long denominator = precision/gcd_; 
    long numerator = round(frac * precision)/gcd_; 

    std::cout << integral << " + "; 
    std::cout << numerator << "/" << denominator << std::endl; 
} 

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

    if (a < b) 
     return gcd(a, b % a); 
    else 
     return gcd(b, a % b); 
} 
+0

Я не думаю, что вы должны делиться знаменателем, и это не найдет «красивую» фракцию, но это разумный подход к получению некоторой сокращенной фракции. –

+1

Этот сайт может помочь некоторым людям понять ваш алгоритм: http://www.webmath.com/dec2fract.html –

+0

@BenVoigt: К сожалению, это была опечатка. – qbt937

0

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

#include <iostream> 
using namespace std; 


// converts the string half of the inputed decimal number into numerical values void converting 
(string decimalNumber, float&numerator, float& denominator) 

{ float number; string valueAfterPoint =decimalNumber.substr(decimalNumber.find("." ((decimalNumber.length() -1))); // store the value after the decimal into a valueAfterPoint 

int length = valueAfterPoint.length(); //stores the length of the value after the decimal point into length 

numerator = atof(valueAfterPoint.c_str()); // converts the string type decimal number into a float value and stores it into the numerator 

// loop increases the decimal value of the numerator by multiples of ten as long as the length is above zero of the decimal 

for (; length > 0; length--) 
    numerator *= 10; 

do 
denominator *=10; 
    while (denominator < numerator); 



// simplifies the the converted values of the numerator and denominator into simpler values for   an easier to read output 


void simplifying (float& numerator, float& denominator) { int maximumNumber = 9; //Numbers in the tenths place can only range from zero to nine so the maximum number for a position in a position for the decimal number will be nine 

bool isDivisble; // is used as a checker to verify whether the value of the numerator has the  found the dividing number that will a value of zero 
// Will check to see if the numerator divided denominator is will equal to zero 


    if(int(numerator) % int(denominator) == 0) { 
    numerator /= denominator; 
    denominator = 1; 
    return; } 


    //check to see if the maximum number is greater than the denominator to simplify to lowest  form while (maximumNumber < denominator) { maximumNumber *=10; } 


// the maximum number loops from nine to zero. This conditions stops if the function isDivisible is true 
for(; maximumNumber > 0;maximumNumber --){ 

isDivisble = ((int(numerator) % maximumNumber == 0) && int(denominator)% maximumNumber == 0); 

    if(isDivisble) 
{ 
    numerator /= maximumNumber; // when is divisible true numerator be devided by the max  number value for example 25/5 = numerator = 5 

    denominator /= maximumNumber; //// when is divisible true denominator be devided by themax  number value for example 100/5 = denominator = 20 

} 


// stop value if numerator and denominator is lower than 17 than it is at the lowest value 
int stop = numerator + denominator; 

if (stop < 17) 
{ 
    return; 
} } } 
Смежные вопросы