Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert floats to human-readable fractions?

Let's say we have 0.33, we need to output 1/3.
If we have 0.4, we need to output 2/5.

The idea is to make it human-readable to make the user understand "x parts out of y" as a better way of understanding data.

I know that percentages is a good substitute but I was wondering if there was a simple way to do this?

like image 643
Swaroop C H Avatar asked Sep 18 '08 19:09

Swaroop C H


People also ask

How do you convert a float number to a fraction?

For example, if input floating point number is 30.25, we convert into fraction as 3025/100. This can be easily done by finding the position of dot. Finally to get the answer, we divide the denominator of the converted fraction by GCD of denominator and numerator.

Can a float be a fraction?

A float can represent 1/2 exactly, as 0.5f . SOME fractions can be represented exactly.

How do you convert a float to a whole number?

Method 1: Conversion using int(): To convert a float value to int we make use of the built-in int() function, this function trims the values after the decimal point and returns only the integer/whole number part.


1 Answers

I have found David Eppstein's find rational approximation to given real number C code to be exactly what you are asking for. Its based on the theory of continued fractions and very fast and fairly compact.

I have used versions of this customized for specific numerator and denominator limits.

/* ** find rational approximation to given real number ** David Eppstein / UC Irvine / 8 Aug 1993 ** ** With corrections from Arno Formella, May 2008 ** ** usage: a.out r d **   r is real number to approx **   d is the maximum denominator allowed ** ** based on the theory of continued fractions ** if x = a1 + 1/(a2 + 1/(a3 + 1/(a4 + ...))) ** then best approximation is found by truncating this series ** (with some adjustments in the last term). ** ** Note the fraction can be recovered as the first column of the matrix **  ( a1 1 ) ( a2 1 ) ( a3 1 ) ... **  ( 1  0 ) ( 1  0 ) ( 1  0 ) ** Instead of keeping the sequence of continued fraction terms, ** we just keep the last partial product of these matrices. */  #include <stdio.h>  main(ac, av) int ac; char ** av; {     double atof();     int atoi();     void exit();      long m[2][2];     double x, startx;     long maxden;     long ai;      /* read command line arguments */     if (ac != 3) {         fprintf(stderr, "usage: %s r d\n",av[0]);  // AF: argument missing         exit(1);     }     startx = x = atof(av[1]);     maxden = atoi(av[2]);      /* initialize matrix */     m[0][0] = m[1][1] = 1;     m[0][1] = m[1][0] = 0;      /* loop finding terms until denom gets too big */     while (m[1][0] *  ( ai = (long)x ) + m[1][1] <= maxden) {         long t;         t = m[0][0] * ai + m[0][1];         m[0][1] = m[0][0];         m[0][0] = t;         t = m[1][0] * ai + m[1][1];         m[1][1] = m[1][0];         m[1][0] = t;         if(x==(double)ai) break;     // AF: division by zero         x = 1/(x - (double) ai);         if(x>(double)0x7FFFFFFF) break;  // AF: representation failure     }       /* now remaining x is between 0 and 1/ai */     /* approx as either 0 or 1/m where m is max that will fit in maxden */     /* first try zero */     printf("%ld/%ld, error = %e\n", m[0][0], m[1][0],            startx - ((double) m[0][0] / (double) m[1][0]));      /* now try other possibility */     ai = (maxden - m[1][1]) / m[1][0];     m[0][0] = m[0][0] * ai + m[0][1];     m[1][0] = m[1][0] * ai + m[1][1];     printf("%ld/%ld, error = %e\n", m[0][0], m[1][0],            startx - ((double) m[0][0] / (double) m[1][0])); } 
like image 85
Epsilon Avatar answered Oct 03 '22 12:10

Epsilon