How to output fraction instead of decimal number?
Asked Answered
M

13

7

In C++, When I calculate 2/3, it will output decimal values, how can I just get the original format (i.e.g 2/3) instead of 0.66666667

Thanks

Monaco answered 27/1, 2011 at 16:35 Comment(5)
It depends on what do you mean by "calculate 2/3"Iodide
This question should come with a code example and the actual and expected output.Partook
There's an interesting demo, showing the working, of converting a decimal to a fraction here: webmath.com/dec2fract.htmlAstigmia
@Tony: Yes, it's interesting, but far from mathematically rigorous, and so I feel it is dangerously misleading for really understanding the subject. It's a start though :-). For a more thorough explanation, see e.g. en.wikipedia.org/wiki/Continued_fractions , in particular the section "Best rational within an interval". (Sorry, I'm a mathematician, couldn't resist...).Grisly
reminds me of 355/113Corelation
T
10

You can't. You would need to write a class dedicated to holding rational numbers (i.e. fractions). Or maybe just use the Boost Rational Number library.

Tedford answered 27/1, 2011 at 16:37 Comment(10)
+1: the obvious solution - just don't throw that information away, indeed!Fortuneteller
There's a finite number of int values that produce 0.66666667. Why not just write a function that picks one? The answer is not "you can't"Apocope
@Inverse: You can't with any reasonable approach. It sounds like you're suggesting the approach of multiplying the floating-point value by all possible denominators until you find a result that's somewhere near an integer value? Obviously, this is of essentially infinite algorithmic complexity (are there better methods?). And even this won't get back "the original format" as requested by the OP; it can't distinguish between 2/3 and 4/6.Tedford
@Inverse: No, there is an infinite number of ints that produce 0.66666667. It might be 1/3, or 1000000/3000001, or 1000001/3000000, etc. (assuming enought zeros to exhaust the FP precision). You can easily show that for any FP number, there is an infinite (though countably infinite) number of integer fractions.Grisly
Of course, in practice you usually want the fraction with the smallest denominator that is reasonably close to your FP number. There is indeed only one such fraction, if you set a fixed limit for the maximum difference between the FP number and the fraction (or if you set an upper bound for the denominator). See my answer for details :-).Grisly
@Oli Charlesworth: Yes, the naive approach of trying all denominators would work, but is obviously quite slow. And yes, there are better ways; the common algorithm uses continued fractions. Pari/GP for example implements this, see my answer.Grisly
@sleske: even if every pair of 32-bit ints produced the value, there would still be a finite number of them, less than 2^64Apocope
@Oli Charlesworth: start with 66666667/100000000, that's O(1). Then run some variation of GCD to reduce the fraction if you want.Apocope
@Inverse: How do you distinguish 66666667/100000000 from 2/3?Tedford
@Inverse: As to "start with 66666667/100000000[...]Then run some variation of GCD". Yes, that would work, if FP could represent all fractions exactly. However, it cannot, so in most cases the fraction you get from the FP representation is not exactly equal to the fraction you started out with. Then you need some kind of approximation algorithm (such as explained in my anser :-) ).Grisly
G
8

If I understand correctly, you have a floating point number (a float or double type variable), and you'd like to output this value as a fraction.

If that is the case, you need to further specify your question:

  • A FP number is a fraction, by definition: A FP number consists of two integers, a mantissa m and an expontent e (and a sign, but that's irrelevant here). So each FP number is really a pair (m,e), and the value f it represents is f=mb^e (where b is a fixed integral base, usually 2). So the natural representation as a fraction is simply m / b^(-e) with e<0 (if e>=0 , f is integral anyway).
  • However, you probably want to get the fraction with the smallest reasonable divisor. This is a different question. To get is, you could e.g. use the bestappr function from the Pari/GP library. In your case, you'd probably use bestappr(x, A), with x your input, and A the largest denominator you want to try. bestappr will give you the fraction closest to x whose denominator is still smaller than A.
Grisly answered 27/1, 2011 at 16:48 Comment(0)
I
6

write your own Rational class to calculate divisions

class Rational
{
public:
    int numerator, denominator;

    Rational(int num, int den=1){
        numerator = num;
        denominator=den;
    }
    Rational(Rational other){
        numerator = other.numerator;
        denominator = other.denominator;
    }
    double operator / (int divisor){
            denominator *= divisor;
            simplificate();
            return getrealformat();
    }
    Rational& operator / (int divisor){
            denominator *= divisor;
            simplificate();
            return this;
    }
    Rational& operator / (Rational &divisor){
            numerator *= divisor.numerator;
            denominator *= divisor.denominator;
            simplificate();
            return this;
    }
    double operator / (int divisor){
            denominator *= divisor;
            simplificate();
        return getrealformat();
    }
    double getrealformat(){
        return numerator/denominator;
    }
    simplificate(){
        int commondivisor = 1;
        for(int i=2;i<=min(abs(numerator), abs(denominator));i++)
            if( numerator%i == 0 && denominator%i == 0 )
                commondivisor = i;
        numerator /= commondivisor;
        denominator /= commondivisor;
    }
};

use

Rational r1(45), r2(90), r3=r1/r2;
cout<<r3.numerator<<'/'<<r3.denominator;
cout<<r3.getrealformat();
Indubitability answered 27/1, 2011 at 17:23 Comment(5)
How does this handle converting from float or double to Rational?Piscatory
Rational operator=(double number){ numerator = number*decimals;/*once specified before, for ex. 100 */ denominator = decimals; simplificate(); }Indubitability
pastebin.com/LhGK3gNG : here I have tried to test above mentioned class. However, I could not use the above code as it is(because it was showing some errors) and I had to rewrite a few things. At the end its not working as expected. Can anybody check what went wrong? @ThomasMatthewsIambic
Thanks for the link, but firewalls are blocking access to the link. Maybe you could edit your post instead?Piscatory
@ThomasMatthews I have created new link: paste.ofcode.org/SVZLDr72BUyEUkam5GrAEt Hope this will workIambic
U
4

how can I just get the original format (i.e.g 2/3) instead of 0.66666667

Only with great difficulty by wrapping something like the GMP library with custom output operators. Below is a bit more on GMP:

What is GMP?

GMP is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating point numbers. There is no practical limit to the precision except the ones implied by the available memory in the machine GMP runs on. GMP has a rich set of functions, and the functions have a regular interface.

The main target applications for GMP are cryptography applications and research, Internet security applications, algebra systems, computational algebra research, etc.

GMP is carefully designed to be as fast as possible, both for small operands and for huge operands. The speed is achieved by using fullwords as the basic arithmetic type, by using fast algorithms, with highly optimised assembly code for the most common inner loops for a lot of CPUs, and by a general emphasis on speed.

GMP is faster than any other bignum library. The advantage for GMP increases with the operand sizes for many operations, since GMP uses asymptotically faster algorithms.

The first GMP release was made in 1991. It is continually developed and maintained, with a new release about once a year.

Unintentional answered 27/1, 2011 at 16:38 Comment(1)
This, or some facility like it is pretty much the only way. You still have to keep track from the start. If you just have 0.6666667, you have no way of knowing if that was 6666667/10000000 or 2/3.Wrens
C
4

You have to store them in some sort of Fraction class with two integer fields. Of course, you have to simplify the fraction before using it for output.

You can develop your own class or use some libraries, like this one for exact maths: CLN - Class Library for Numbers

Criminality answered 27/1, 2011 at 16:46 Comment(2)
A class with two integer fields: nominator and denominator doesn't help with the conversion of float or double to a fraction. The conversion to a fraction can occur with a Fraction class.Piscatory
Thomas, I don't get the difference. However, also float and double are fractions, in a way. As I understood it, the question was about how to manage the issue from the beginning, and the solution is to avoid the creation of float or double variables in the first place.Criminality
F
3

This is impossible in general: floating point numbers are not precise and do not retain sufficient information to fully reconstruct a fraction.

You could, however, write a function that heuristically finds an "optimal" approximation, whereby fractions with small numerators and denominators are preferred, as are fractions that have almost the same value as the floating point number.

If you're in full control of the code, Oli's idea is better: don't throw away the information in the first place.

Fortuneteller answered 27/1, 2011 at 16:36 Comment(4)
That's not QUITE true. If you have a specific precision you're willing to live with (say, 0.00001), you could multiply by the inverse of that precision - which gives you a large numerator and denominator. It would be possible at that point to factorize both numerator and denominator, then start removing common factors until you're left with the smallest fraction that yields a floating-point value that is within the precision you specified of the original floating-point number.Durban
You mean: it's not always true, for all floating point numbers. To be more precise then: for any floating point number, there are a countable infinity of rational numbers at least as close to it as to other floating point numbers, although exactly one of those rational numbers is exactly equal to the floating point number. Is that better?Fortuneteller
@BobG: that algorithm will generally not find the "optimal" fraction since the hand-picked initial denominator (1/0.00001 in your example) is not divisible by the optimal divisor (e.g. the "3" in Sean's example). Anyhow, this sounds like a different question...Fortuneteller
At any rate, implementing an algorithm for finding the best rational approximation is not necessary; such implementations already exist, for example in Pari/GP (see my answer).Grisly
T
2

You can store all your fraction's numerators and denominators as intergers. Integers have exact representations in binary.

Titanate answered 27/1, 2011 at 16:40 Comment(3)
...until they don't. There is a max int, past which you'd have to use some kind of bignum library. Or floating-point, which gets him back to his original problem.Wrens
@T.E.D., overflowing ints was not OP's problem.Titanate
i'd say 1/10^20 is sufficient precision for almost any application.Woo
P
2

To simplify efforts, I suggest you stick with known denominators if possible.

I'm working with an application where the fractions are restricted to denominators of powers of 2 or using 3 (for thirds).

I convert to these fractions using an approximation (rounding to the nearest 1.0/24.0).

Without some restrictions, finding the denominator can be quite a chore and take up a lot of the execution time.

Piscatory answered 27/1, 2011 at 18:36 Comment(0)
C
0

I am beginner and this way that I use may not be a proper way

#include <iostream>

using namespace std;
int main ()
{
  double a;
  double b;
  double c;

  cout << "first number: ";
  cin >> a;
  cout << "second number: ";
  cin >> b;

  c = a/b;
  cout << "result is: " << c << endl;

  if (b != 0) {
    if (a > 0) {
      if (c - (int)c > 0 && c - (int)c < 1)
        cout << "fraction: " << a << "/" << b;
    } else {
      if (c - (int)c < 0 && c - (int)c < 1)
        cout << "fraction: " << a << "/" << b;
    }
  }

  return 0;
}
Coattail answered 10/6, 2013 at 7:12 Comment(8)
I think you answered a different question. Your answer is about separating the integer-part of a floating point number from the non-integer part (i.e. separate 1.25 into 1 and .25). But the question is about transforming the floating point number into a fraction-representation of a rational number, i.e. 1 1/4 or 5/4.Genocide
With this you can recognize floating result and print them in fraction wayCoattail
For 1.25 your program outputs 1 and .25, correct? How does it transform .25 into 1/4?Genocide
Ok guys I just edited it with that way I said :) check it out and leave comment :)Coattail
But now your program requires the user to entire a and b explicitly. Some of the other answers said this too; if a rational number is given as input, you could simply store it so you have it when you need it. But the real difficulty is in calculating a and b from the floating point number.Genocide
Sorry I didn't understand what you mean !!! But I tried this one for many numbers and it gave the correct output !Coattail
What I mean is: Try and write a program where the user enters only c, and the program calculates a and b. But anyway... it's not that important.Genocide
Oh I see !!! I will try but I'm just a beginner ! and the question is about calculating a and b and their fractional result.Coattail
L
0

Dividing both numbers with their HCF might help.

Landre answered 9/6, 2014 at 8:52 Comment(0)
K
0
#include <iostream>
using namespace std;

int main() {
    int a,b,q,r;
    cin>>a>>b;//first number and second number
    q = a/b;
    r = a-q*b;
    cout<<q<<" "<<r<<" "<<"/"<<" "<<b<<"\n";
    return 0;
}

I just got quotient by a/b then got the remainder by a-q*b. open for suggetions if any.

Kulsrud answered 6/10, 2015 at 21:46 Comment(0)
B
0

Use greatest common divisor concept.

if we divide the numbers with gcd of their numbers we get least possible value of those.example:-

#define si long long
int main() {
si int total=4;
si int count=2;
si int g= __gcd(count,total);
count/=g;
total/=g;
cout<<count<<"/"<<total<<endl;
}
for more reference check out this:-https://www.codechef.com/viewsolution/17873537
Boyt answered 18/3, 2018 at 3:11 Comment(0)
N
-1

This is a program to convert a decimal number into a fraction

#include<iostream>
using namespace std;

int main()
{

    float num, origNum, rem = 1;
    int den = 1, i, count=0, gcd=1;

    cout << "Enter any float number to convert it into mixed fraction: ";
    cin >> origNum;

    num = origNum - static_cast<int>(origNum);

    if (num > 0.1)
    {
        while ( (rem > 0.1) )
        {
            num = num * 10;
            rem = num - static_cast<int>(num);
            count++;
        }

        for (i = 1; i <= count; i++) // counter is for the calculation of denominator part of mixed fraction 
        {
            den = den * 10;
        }

        for (i = 2; i <= num|| i<=rem; i++)
        {
            if( (static_cast<int>(num) % i == 0) && (den % i == 0) )
            {
                gcd = i;
            }   
        }

        cout << (static_cast<int>(origNum)) << " and " << (static_cast<int>(num))/gcd << "/" << den/gcd;
    }
    else
        cout << (static_cast<int>(origNum));

    return 0;   
}
Nonrecognition answered 22/2, 2015 at 20:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.