1

I need to turn small percentages into large fractions. If I have a percentage of 0.000126% - I would like to put this into a fraction of something like 1/10,000 - etc. How, do I turn a small percentage into a fraction that is not the lowest common fraction.

The answer to the equation is simple.

0.000126% = 0.00126/10% = 0.0126/100% = 0.126/1000% = ... = 126/1000000%

Then find common factors. 2 goes into each, so that's the same as 63/500000. That's as simple as I can make it.

Thus, in code - how do I get this damn fraction. Grrrr.... frustrating o.O! Several attempts - and I'm failing at each. Any ideas?

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
James Cordeiro
  • 521
  • 1
  • 5
  • 8
  • 1
    Cnotinuous fractions theory should help you. Read this: http://stackoverflow.com/questions/95727/how-to-convert-floats-to-human-readable-fractions – ypercubeᵀᴹ Feb 16 '13 at 09:47
  • 3
    You're going to have a bad time. Php cannot accurately store `0.000126`, just like you cannot represent 1/3 in decimal. – Eric Feb 16 '13 at 09:53
  • 1
    @Eric: PHP may not have out of the box fraction support but the OP is trying to do just that. Floats cannot accurately store many numbers but fractions can. It's not hard at all. – ypercubeᵀᴹ Feb 16 '13 at 09:56
  • Then the OP will need to parse fractions from a string. If you try to get an exact fractional representation of a float, then you've lost. A better goal might be "find the closest fraction with a denominator below 1000" – Eric Feb 16 '13 at 10:29
  • 1
    essentially, you could write a function such that `fractionify("0.000126") == array(63, 500000)`, but you wouldn't be able to make `fractionify(0.000126) == array(63, 500000)` – Eric Feb 16 '13 at 10:44
  • I've turned binomial coefficients and permutations of trillions, into easy to read percentages that PHP can interpret using every method I could derive at. Now I'm trying to turn the small percentiles, into a fraction that is readable. I understand what you're referring to, Eric. But I refuse to stand at a wall, lol. I don't care if it's ridiculously hard - I just need a direction to go, and I'll get to my answer. The continuous fraction theory which @ypercube has led me to - http://stackoverflow.com/questions/95727/how-to-convert-floats-to-human-readable-fractions - is a good start. – James Cordeiro Feb 16 '13 at 11:01
  • Thank you for the input guys :) I'm further than I was an hour ago, lol – James Cordeiro Feb 16 '13 at 11:03

1 Answers1

2

Here's a PHP function that uses continued fractions to find a rational approximation to a given (positive) floating point number with a relative error less than a given tolerance.

<?php
function float2frac($n, $tolerance = 1.e-6) {
    $h1=1; $h2=0;
    $k1=0; $k2=1;
    $b = $n;
    do {
        $a = floor($b);
        $aux = $h1; $h1 = $a*$h1+$h2; $h2 = $aux;
        $aux = $k1; $k1 = $a*$k1+$k2; $k2 = $aux;
        $b = 1/($b-$a);
    } while (abs($n-$h1/$k1) > $n*$tolerance);

    return "$h1/$k1";
}

printf("%s\n", float2rat(66.66667)); # 200/3
printf("%s\n", float2rat(sqrt(2)));  # 1393/985

I have written more about this algorithm and why it works, and even a JavaScript demo here: http://jonisalonen.com/2012/converting-decimal-numbers-to-ratios/

Joni
  • 108,737
  • 14
  • 143
  • 193