Fractions instead of decimals

醉酒当歌 提交于 2019-12-02 10:04:41

A nice way to approximate a float with a fraction is to used continued fractions. In the following code, epsis the desired precision. xis assumed to be strictly positive.

#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;
}

Detailed information on continued fractions is available on Wikipedia for example.

If you don't need a high precision or if you assume that the denominators will be small, you can use a brute force approach instead, simply incrementing the denominator b.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!