<ratio>

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/
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
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.
@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
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


At least they are consistently mangling math container names. cough vector, cough.
@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';
}

@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
@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.