Фракции вместо десятичных дробей - PullRequest
0 голосов
/ 12 ноября 2018

Итак, я пишу эту маленькую программу на c ++, она предназначена для вычисления различных значений с помощью строк (извините, я француз, я не знаю, как сказать это по-английски, но это строки с типами уравнений Y = кх + т). И я хочу, чтобы моя программа выводила дроби вместо десятичных дробей (2/3 вместо 0,666666666 ...).

Может кто-нибудь сказать мне, как?

Я читал в Интернете, что для этой цели есть несколько библиотек, кто-нибудь может мне помочь, как их использовать и / или как реализовать их в моем коде? Спасибо:)

#include "pch.h"
#include <iostream>
#include <string>

std::string mainAnswer;
bool endVar = false;

void lineEquationFromTwoPoints() {
    mainAnswer.clear();
    double Xa = 0;
    double Ya = 0;
    double Xb = 0;
    double Yb = 0;
    double Y = 0;
    double X = 0;
    double k = 0;
    double t = 0;

    std::cout << ("Enter the Coordinates of your first point in this format x y : ");
    std::cin >> Xa >> Ya;
    std::cout << ("Enter the Coordinates of your second point in this format x y : ");
    std::cin >> Xb >> Yb;

    if (Xb != Xa && Yb != Ya) {
        k = (Yb - Ya) / (Xb - Xa);
        t = -(Xa)*k + Ya;

        if (k != 1 && t != 0) {
            std::cout << ("Y = ") << k << ("x + ") << t << std::endl;
        }
        else if (k == 1) {
            std::cout << ("Y = ") << ("x") << ("+") << t << std::endl;
        }
        else if (t == 0) {
            std::cout << ("Y = ") << k << ("x") << std::endl;
        }
    }
    else if (Xb == Xa) {
        std::cout << ("Coordinates of the first point are Equal");
    }
    else if (Yb == Ya) {
        std::cout << ("Coordinates of the second point are Equal");
    }
    else if (Xb == Xa && Yb == Ya) {
        std::cout << ("Coordinates of both points are Equal");
    }
}

void triangle() {
    double Xa = 0;
    double Ya = 0;
    double Xb = 0;
    double Yb = 0;
    double Xc = 0;
    double Yc = 0;
    double Ym1 = 0;
    double Xm1 = 0;
    double km1 = 0;
    double tm1 = 0;
    double Ym2 = 0;
    double Xm2 = 0;
    double km2 = 0;
    double tm2 = 0;
    double Ym3 = 0;
    double Xm3 = 0;
    double km3 = 0;
    double tm3 = 0;

    std::cout << ("Work in progress. . . :-)") << std::endl;
}

void Choose() {
    while (endVar != true) {
        std::cout << ("Lines:") << std::endl;
        std::cout << ("------") << std::endl << std::endl;
        std::cout << ("Choose What Line Operations do You Want Me To Perform:") << std::endl;
        std::cout << ("1.Formulas") << std::endl;
        std::cout << ("2.Calculation of a Line's equation from 2 points") << std::endl;
        std::cout << ("3.Calculation of all data in a triangle") << std::endl;
        std::cout << ("Type Exit to Exit") << std::endl << std::endl;
        std::getline(std::cin, mainAnswer);
        if (mainAnswer == "exit" || mainAnswer == "Exit") {
            std::exit;
            endVar = true;
        }
        else if (mainAnswer == "1") {
            std::cout << ("Formulas will be added Here once main program with main calculation functions will be finished") << std::endl;
        }
        else if (mainAnswer == "2") {
            lineEquationFromTwoPoints();
        }
        else if (mainAnswer == "3") {
            triangle();
        }
        else {
            std::cout << ("Unexpected error occured. Please relaunch program.");
            std::exit;
        }
    }
}

int main()
{
    Choose();
    return 0;
}

1 Ответ

0 голосов
/ 13 ноября 2018

Хороший способ приблизить число с плавающей запятой - использовать непрерывные дроби. В следующем коде eps - желаемая точность. x предполагается строго положительным.

#include    <iostream>
#include    <iomanip>
#include    <cmath>
#include    <tuple>
#include    <vector>
#include    <cmath>

//  Continued fraction
std::pair<int, int> fract_cont (double x, double eps = 1.0e-3) {
    std::vector<int> a;
    std::vector<int> b;
    a.push_back(1);
    b.push_back(0);
    int q = int(x);
    a.push_back(q);
    b.push_back(1);
    double err = x - q;
    double e = (x != q) ? 1.0 / (x - q) : 0.0;
    int i = 1;

    while (std::abs(err) > eps) {
        i++;
        q = int (e);
        e = 1.0 / (e - q);
        a.push_back (q * a[i-1] + a [i-2]);
        b.push_back (q * b[i - 1] + b[i-2]);
        err = x - double (a[i]) / b[i];
    } 
    return std::make_pair(a[i], b[i]);
}

int main() {
    int a, b;
    double x = 4 * atan(1.0);
    std::tie (a,b) = fract_cont(x);
    std::cout <<"Pi = " << std::setprecision(9) << x << " ~= " << a << "/" << b << "\n";
    return 0;
}

Подробная информация о продолжающихся дробях доступна, например, в Википедии.

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

...