Displaying fractions as 1/8 rather than .125 ?

I have made a program that displays a grid size for tile installations.

My friend is familiar with fractions, but I know he will be confused when he sees (for example) 20.125, which is 20 and 1/8. How can I make my program display the fractional part of the values as fractions rather than decimal numbers? Any help would be greatly appreciated.. Below is the code:

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <cstdlib>
#include <iostream>
#include <windows.h> // For using colors
using namespace std;
WORD GetConsoleTextAttribute (HANDLE hCon)
{
     // For addings colors
  CONSOLE_SCREEN_BUFFER_INFO con_info;
  GetConsoleScreenBufferInfo(hCon, &con_info);
  return con_info.wAttributes;
}

int main(int argc, char *argv[])
{
    // For adding colors
    {
  HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  const int saved_colors = GetConsoleTextAttribute(hConsole);
    
    cout << "\n";
    cout << "\n";
    cout << "This program is designed to make establishing your grid sizes a lot easier.\n";
    cout << "Simply enter your grid size, and the program will create the rest of the grid\n";
    cout << "for you!\n";
    
    float x, a, b, c, d, e, f, g, h;
    
    cout << "Please enter a grid size: \n";
    cout << "\n";
    cout << "\n";
    
    cin >> x;
    a = x+x;
    b = x + a;
    c = x + b;
    d = x + c;
    e = x + d;
    f = x + e;
    g = x + f;
    h = x + g;
    cout << " \n";
    cout << " \n";
    cout << " \n";
    cout << "A: -----> " << x << "\n";
    SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    cout << "B: -----> " << a << "\n";
    SetConsoleTextAttribute(hConsole, saved_colors);
    cout << "C: -----> " << b << "\n";
    SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    cout << "D: -----> " << c << "\n";
    SetConsoleTextAttribute(hConsole, saved_colors);
    cout << "E: -----> " << d << "\n";
    SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    cout << "F: -----> " << e << "\n";
    SetConsoleTextAttribute(hConsole, saved_colors);
    cout << "G: -----> " << f << "\n";
    SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    cout << "H: -----> " << g << "\n";
    SetConsoleTextAttribute(hConsole, saved_colors);
    cout << "I: -----> " << h << "\n";
    cout << " \n";
    cout << " \n";
    cout << " \n";
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}
Hi,

The only way that I can think of works with this equation:

x/y = z

x = numerator (1)
y = denominator (8)
z = your decimals (.125)

You have z from the decimal number that you have.
As for y, would you want to use a constant value here, always 8? If so, that's ok, if not then perhaps get the user to enter one.

Using z and y, you can then work out x and x/y will be your fraction.
if you have a decimal less than 1 e.g 0.125 change it to a fractional like 125 / 1000. so 0.xxx becomes xxx / 10 ^ (number of decimal places). Then divide top and bottom by their highest common factor and that will give you the decimal number as a fraction.
example / pseudocode:

1
2
3
4
5
6
7
8
9
10
11
12
double decimal = 0.125;
int dec_places = getNumDecPlaces(decimal)- in this case it should return 3;

int numerator = decimal * 10 ^ dec_places - this will be 125;
int denominator = 10 ^ dec_places;

int hcf = getHighestCommonFactor(numerator, denominator);

numerator = numerator / hcf;
denominator = denominator  hcf;

cout << decimal  << " = " << numerator  << "/" << denominator ;


Note: This is just some pseudocode to help you get my idea. It will NOT compile. Hope it helps.
Last edited on
With floating point values, it will be common to have numbers like 1.99999999 rather than 2. And I guess your friend will not like (1 + 9999999/10000000) fractions.
My solution would be to make a fraction class, which will hold two integer values (numerator and denominator), and overload the mathematical operators. I once made something like this. If you want I can post it here.
While the best solution is the one suggested by R0mai, I'd like to post a terrible way to do this. A low level approach:
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
#include <iostream>

const int m_bits = 23, e_bits = 8, s_bits = 1, bits = 32;

void print(float f){
    //extract significant groups of bits.
    unsigned data = *((int*)&f);
    unsigned mnt = (1<<m_bits) + (data & ((1<<m_bits)-1));
    unsigned exp = (data >> m_bits);
    unsigned sgn = data >> (bits-s_bits);

    //calculate numerator and denominator
    int num = sgn ? -mnt : mnt;
    unsigned den = 1 << (23-exp+127);

    //divide them by their largest common divisor.
    int i=0, t=1;
    for(i = 0, t = 1; i < 32 && (num&t)==0 && (den&t)==0; i++, t<<=1);
    num >>= i;
    den >>= i;

    std::cout << f << "=" << num << "/" << den;
    return;
}

int main(){
    print(0.125);
    std::cin.get();
    return 0;
}

To better understand how this works, see http://en.wikipedia.org/wiki/Single_precision_floating-point_format
R0mai - If you could post it I would appreciate it - just to see an example would be good.

It seems like from everyone's responses, that what I'm trying to do is quite complicated lol. Of course, my friend may run into more than just .125 (1/8) He may also run into .375 (3/8) and so and so on..

If you compile and run the program you'll see what I mean :)

Perhaps it would be simpler to display the value as it comes out e.g. (20.125) and then create a function in the program to identify what fraction it is? Therefore if 20.125 comes out, he can enter it and it will display it as 20 1/8 ?

I'm new to C++ so I may not be the best at conveying my ideas using the proper terms, so please bear with me :)

But what do you guys think of that idea?
Code below.
example usage:

1
2
3
4
5
6
#include "fraction.h"

int main() { //Warning: not tested
    math::fractioni f(4,5);
    std::cout << (f + math::fractioni(3, 8) - 1)/math::fractioni(2, 3) << std::endl;
}


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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#ifndef FRACTION_H_
#define FRACTION_H_

#include <iostream>

#include <boost/operators.hpp>

namespace math {

template<class T>
T gcd(T n1, T n2) {
    while (n2 != 0) {
        T t = n2;
        n2 = n1 % n2;
        n1 = t;
    }
    return n1;
}

template<class num_T>
class fraction:
    boost::arithmetic< fraction<num_T> >,
    boost::arithmetic< fraction<num_T> , num_T>,
    boost::subtractable2_left< fraction<num_T> , num_T>,
    boost::dividable2_left< fraction<num_T> , num_T>,
    boost::totally_ordered< fraction<num_T> >,
    boost::totally_ordered< fraction<num_T>, num_T >{
public:

    num_T numerator;
    num_T denominator;

    fraction();
    fraction(const num_T& numerator, const num_T& denominator);
    fraction(const fraction<num_T>& rhs);
    fraction(const num_T& rhs);

    fraction<num_T>& operator =(const fraction<num_T>& rhs);
    fraction<num_T>& operator =(const num_T& rhs);

    fraction<num_T>& operator+=(const fraction<num_T>& rhs);
    fraction<num_T>& operator-=(const fraction<num_T>& rhs);
    fraction<num_T>& operator*=(const fraction<num_T>& rhs);
    fraction<num_T>& operator/=(const fraction<num_T>& rhs);

    fraction<num_T>& operator+=(const num_T& rhs);
    fraction<num_T>& operator-=(const num_T& rhs);
    fraction<num_T>& operator*=(const num_T& rhs);
    fraction<num_T>& operator/=(const num_T& rhs);

    bool operator<(const fraction<num_T>& rhs) const;
    bool operator<(const num_T& rhs) const;

    bool operator==(const fraction<num_T>& rhs) const;
    bool operator==(const num_T& rhs) const;

    template<class float_T>
    float_T getvalue();

    //making reciprocal
    fraction<num_T> operator ~() const;
    fraction<num_T> reciprocal() const;

    fraction& simplify();

    static void make_common_denominator(fraction<num_T>& f1, fraction<num_T>& f2);

};
//-
typedef fraction<int> fractioni;

//-------------------------------------IMPLEMENTATION-----------------------------------

template<class num_T>
fraction<num_T>::fraction() :
    numerator(), denominator(1) {
}

template<class num_T>
fraction<num_T>::fraction(const num_T& numerator, const num_T& denominator) :
    numerator(numerator), denominator(denominator) {
}

template<class num_T>
fraction<num_T>::fraction(const fraction<num_T>& rhs) :
    numerator(rhs.numerator), denominator(rhs.denominator) {
}

template<class num_T>
fraction<num_T>::fraction(const num_T& rhs) :
    numerator(rhs), denominator(1) {

}

template<class num_T>
inline fraction<num_T>& fraction<num_T>::operator=(const fraction<num_T>& rhs) {
    numerator = rhs.numerator;
    denominator = rhs.denominator;
    return *this;
}

template<class num_T>
inline fraction<num_T>& fraction<num_T>::operator=(const num_T& rhs) {
    numerator = rhs;
    denominator = 1;
    return *this;
}

template<class num_T>
inline fraction<num_T>& fraction<num_T>::operator+=(const fraction<num_T>& rhs) {
    fraction<num_T> tmp(rhs);
    make_common_denominator(*this, tmp);

    numerator += tmp.numerator;
    return *this;
}

template<class num_T>
inline fraction<num_T>& fraction<num_T>::operator-=(const fraction<num_T>& rhs) {
    fraction<num_T> tmp(rhs);
    make_common_denominator(*this, tmp);

    numerator -= tmp.numerator;
    return *this;
}

template<class num_T>
inline fraction<num_T>& fraction<num_T>::operator*=(const fraction<num_T>& rhs) {
    numerator *= rhs.numerator;
    denominator *= rhs.denominator;
    return *this;
}

template<class num_T>
inline fraction<num_T>& fraction<num_T>::operator/=(const fraction<num_T>& rhs) {
    *this *= ~rhs;
    return *this;
}

template<class num_T>
inline fraction<num_T>& fraction<num_T>::operator+=(const num_T& rhs) {
    numerator += (denominator * rhs);
    return *this;
}

template<class num_T>
inline fraction<num_T>& fraction<num_T>::operator-=(const num_T& rhs) {
    numerator -= (denominator * rhs);
    return *this;
}

template<class num_T>
inline fraction<num_T>& fraction<num_T>::operator*=(const num_T& rhs) {
    numerator *= rhs;
    return *this;
}

template<class num_T>
inline fraction<num_T>& fraction<num_T>::operator/=(const num_T& rhs) {
    denominator *= rhs;
    return *this;
}

template<class num_T>
bool fraction<num_T>::operator<(const fraction<num_T>& rhs) const {
    return rhs.denominator * numerator < denominator * rhs.numerator;
}

template<class num_T>
bool fraction<num_T>::operator<(const num_T& rhs) const {
    return numerator < denominator * rhs;
}

template<class num_T>
bool fraction<num_T>::operator==(const fraction<num_T>& rhs) const {
    return rhs.denominator * numerator == denominator * rhs.numerator;
}

template<class num_T>
bool fraction<num_T>::operator==(const num_T& rhs) const {
    return numerator == denominator * rhs;
}

template<class num_T>
template<class float_T>
float_T fraction<num_T>::getvalue() {
    return float_T(numerator) / float_T(denominator);
}

template<class num_T>
inline fraction<num_T> fraction<num_T>::operator~() const {
    return reciprocal();
}

template<class num_T>
inline fraction<num_T> fraction<num_T>::reciprocal() const {
    return fraction(denominator, numerator);
}

template<class num_T>
inline fraction<num_T>& fraction<num_T>::simplify() {
    num_T g = gcd(numerator, denominator);
    numerator /= g;
    denominator /= g;
    return *this;
}

template<class num_T>
inline void fraction<num_T>::make_common_denominator(fraction<num_T>& f1, fraction<num_T>& f2) {
    fraction<num_T> tmp(f1);
    f1.numerator *= f2.denominator;
    f1.denominator *= f2.denominator;

    f2.numerator *= tmp.denominator;
    f2.denominator *= tmp.denominator;

}

template<class charT, class traits, class T>
std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const fraction<T>& rhs) {
    os << '(' << rhs.numerator << '/' << rhs.denominator << ')';
    return os;
}

template<class num_T, class exp_T>
fraction<num_T> pow(const fraction<num_T>& base, exp_T exp) {
    fraction<num_T> res(base);

    if (exp < 0) {
        while (++exp) {
            res.numerator *= base.numerator;
            res.denominator *= base.denominator;
        }
        return ~res;
    } else if ( exp > 0 ) {
        while (--exp) {
            res.numerator *= base.numerator;
            res.denominator *= base.denominator;
        }
        return res;
    } else { //exp == 0
        return fraction<num_T>(1,1);
    }
}

} //namespace math

#endif /* FRACTION_H_ */ 
Topic archived. No new replies allowed.