How to retain fraction form, not decimal of division

I need to set something up whereby the result of 10/4 = 10/4, not 2.5. Basically if the result isn't an integer, I need my calculation to remain as an integer, even if that means it remains as a fraction.

www.sagemath.com equations seem to permit this, but I can't seem to get C++ to do that. The conversion to decimal keeps screwing up my equations.

Only solution I've found is semi-complicated and adds additional calculations I don't need.

Currently my divisions are resulting in 0 (because I'm using 256 and 512 bit integers).
Last edited on
You will have to make a fraction class. Shouldn't be too trivial. Or you could even just make a division function. Something like:

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
void simplify(int &numerator, int &denominator)
{
    int max = numerator > denominator ? numerator : denominator;
    for(int i = max; i > 1; --i) //no need to check if divisible by 1
   {
        if(!(numerator % i) && !(denominator % i)) //divides evenly into both
       {
            numerator /= i;
            denominator /= i;
            break;
       }
   }
}
std::string divide(int numerator, int denominator)
{
    simplify(numerator, denominator); //put in reduced form
    if(!(numerator % denominator)) //if there is no remainder
    {
        numerator /= denominator;
    }
    std::stringstream ss;
    if(denominator > 1)
    {
        ss << numerator << "/" << denominator;
    }
    else
    {
        ss << numerator;
    }
    return ss.str();
}




here is a demo version:
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
#include <iostream>
#include <string>
#include <sstream>

void simplify(int &numerator, int &denominator)
{
    int max = numerator > denominator ? numerator : denominator;
    for(int i = max; i > 1; --i) //no need to check if divisible by 1
   {
        if(!(numerator % i) && !(denominator % i)) //divides evenly into both
       {
            numerator /= i;
            denominator /= i;
            break;
       }
   }
}
std::string divide(int numerator, int denominator)
{
    simplify(numerator, denominator); //put in reduced form
    if(!(numerator % denominator)) //if there is no remainder
    {
        numerator /= denominator;
    }
    std::stringstream ss;
    if(denominator > 1)
    {
        ss << numerator << "/" << denominator;
    }
    else
    {
        ss << numerator;
    }
    return ss.str();
}

int main()
{
    int numerator;
    int denominator;
    char junk;
    while(std::cout << "Please enter fraction: " && std::cin >> numerator >> junk >> denominator)
    {
        std::cout << numerator << junk << denominator << " = " << divide(numerator, denominator) << std::endl;
    }
}


PS I coded pretty fast so it's probably not very neat, efficient, and may have bugs.


[edit]added the missing '[' in code tags.[/edit]
Last edited on
I think you've got a good idea, but I still need to be able to use these fractions with other equations in the program such that they never fully divide unless I'm working with only an integer. As soon as I re-apply your code, I think it'd simplify.
You might want to consider a library created for this kind of numerical work:

https://gmplib.org/

This may apply to your needs:
https://gmplib.org/manual/Rational-Number-Functions.html#Rational-Number-Functions

And converting to basic types:
https://gmplib.org/manual/Rational-Conversions.html#Rational-Conversions
Using boost::rational<> would feel a whole lot more like programming in C++.
http://www.boost.org/doc/libs/1_55_0/libs/rational/rational.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>

template < typename INTEGER_TYPE = int > using rational = boost::rational<INTEGER_TYPE> ;

int main()
{
    rational<> a = 7 ; // 7/1
    rational<> b( 44, 14 ) ; // 22/7
    rational<> c = a*a + b*b - 2*a*b ;
    std::cout << a << '\n' << b << '\n' << c << '\n' ;
    
    using boost::multiprecision::cpp_int ;
    rational<cpp_int> d( cpp_int("12345678987654321"), cpp_int("123456789") ) ;
    std::cout << d << '\n' << d + 25000000 << '\n' ;
    
    std::cout << d / boost::rational_cast<cpp_int>(c) << '\n' ;
}

g++-4.8 -std=c++11 -O2 -Wall -Wextra -pedantic-errors main.cpp && ./a.out
7/1
22/7
729/49
1371742109739369/13717421
1714677634739369/13717421
1371742109739369/192043894

http://coliru.stacked-crooked.com/a/f7945b172844733b
JLBorges, That was perfect! (EDIT: removed questions etc that I was able to answer for myself)

How do I MOD this number and or convert it back into the "INTEGER_TYPE" it was before I rational<>'d it? When I make the same int = the rational<>'d number it throws an error.
Last edited on
1
2
3
4
5
6
7
8
boost::rational<int> r( 44, 14 ) ; // 22/7

int numerator = r.numerator() ;
int denominator = r.denominator() ;

double value = double(numerator) / denominator ;
int quotient = numerator / denominator ;
int remainder = numerator % denominator ;
Topic archived. No new replies allowed.