<ratio>

Jun 22, 2018 at 3:39pm
I was looking to see if there was a variable that could store a ratio. Then I saw the header <ratio> and thought cool. But upon closer look it seems that this does not hold a ratio but rather a fraction. 2/3 is not the same as 2:3.

Am I mistaken? Can someone enlighten me on this subject?


http://www.cplusplus.com/reference/ratio/ratio/
Jun 22, 2018 at 4:02pm
No, you are not mistaken. It holds a rational number, not a "ratio" per se. Rational numbers are more generally useful. But the rational numbers of <ratio> are set at compile time. So you probably want to make your own ratio class.
Last edited on Jun 22, 2018 at 4:10pm
Jun 22, 2018 at 4:11pm
That "ratio" is just a named constant that has two integers, rather than one. What you do with the values is up to you.

While you can do some "math operations" with the ratio, they are all compile-time computations. constexpr.
1
2
3
using cake = std::ratio<2,3>;
std::cout << "Put " << cake:num << " cups of flour and ";
std::cout << cake:den << " cups of milk into a kettle.\n";



You probably yearn for more traditional variables, whose values you can change during runtime, say by input.
Jun 22, 2018 at 4:33pm
@keskiverto, I had initially assumed that <ratio> would be something more useful than that. Taking a peek at the docs, I modified my answer just before you posted! But it's slightly more than just two integers since it will reduce them to lowest terms (so you don't always get exactly the same integers back; just the same ratio).
Last edited on Jun 22, 2018 at 4:34pm
Jun 22, 2018 at 4:55pm
OK, so I see. My error was in the name. It is not an actual ratio variable, which might have been cool actually. A variable that could be modified as needed...

1
2
3
4
5
6
ratio r1 = 2:3;
ratio r2 = 2:5;

ratio r3 = r1 + r2;

cout << r3;
and the out put would be like...

1:2


Jun 22, 2018 at 4:58pm
At least they are consistently mangling math container names. cough vector, cough.
Jun 22, 2018 at 5:33pm
@Manga,
2:3 is the fraction 2/5.
2:5 is the fraction 2/7.
2/5 + 2/7 is 24/35
24/35 as a ratio is 24:11


Example code that does this:

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
#include <iostream>
#include <stdexcept>

class Fraction {
    int num, den;

    static int calc_gcd(int x, int y) {
        while (y != 0) { int t = y; y = x % y; x = t; }
        return x;
    }
    void normalize() {
        if (den < 0) { den = -den; num = -num; }
        int gcd = calc_gcd(num, den);
        num /= gcd;
        den /= gcd;
    }
public:
    Fraction(int num, int den = 1) : num(num), den(den) {
        if (den == 0) throw std::invalid_argument("fraction denominator is zero");
        normalize();
    }
    void set(int n, int d) { num = n; den = d; normalize(); }
    int numerator() const { return num; }
    int denominator() const { return den; }
    Fraction operator+(Fraction f) {
        return Fraction(f.num * den + num * f.den, f.den * den);
    }
    friend std::ostream& operator<<(std::ostream& os, const Fraction& frac) {
        return os << frac.num << '/' << frac.den;
    }
};

class Ratio {
    Fraction f;
public:
    Ratio(int a, int b) : f(a, a + b) {}
    Ratio(Fraction f) : f(f) {}

    Ratio operator+(Ratio y) { return Ratio(f + y.f); }

    friend std::ostream& operator<<(std::ostream& os, const Ratio& rat) {
        return os << rat.f.numerator() << ':'
                  << rat.f.denominator() - rat.f.numerator();
    }
};

int main() {
    Ratio r1(2, 3), r2(2, 5);
    Ratio r3 = r1 + r2;
    std::cout << r1 << '\n';
    std::cout << r2 << '\n';
    std::cout << r3 << '\n';
}

Jun 23, 2018 at 12:15pm
@tpb

I don't think I agree with the math here...

It is time to use the apples and oranges example.

If I have a pile containing 2 apples and 3 oranges, then the ratio is 2:3.

If I have a pile containing 2 apples and 5 oranges, then the ratio is 2:5.

If I add them all together I have 4 apples and 8 oranges. This is 1:2 ratio not 24:11. How did your end result give you more apples then oranges?
Last edited on Jun 23, 2018 at 12:17pm
Jun 23, 2018 at 1:19pm
@tpb

Ok. It looks like I am adding quantities in my example not the ratios. I will take a moment now and thank you for making my life so complicated...
Topic archived. No new replies allowed.