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?

7
  • 1
    Cnotinuous fractions theory should help you. Read this: stackoverflow.com/questions/95727/… Commented Feb 16, 2013 at 9: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. Commented Feb 16, 2013 at 9: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. Commented Feb 16, 2013 at 9: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" Commented Feb 16, 2013 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) Commented Feb 16, 2013 at 10:44

1 Answer 1

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/

Sign up to request clarification or add additional context in comments.

1 Comment

Well done, @Joni - thank you. That's brilliant work.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.