 # Converting a Decimal to a Fraction in PHP

Below is a helper function to convert a decimal, like for instance 6.5, into a fraction, 13/3 in this example. In fact the function will return an array with the number on the top of the fraction (the numerator) being the first item and the number at the bottom (the denominator) being the second item.

Edit 25th Nov 2016: Changed the function to be more accurate and added some phpunit tests for it.

The Function:

``````/**
* Convert a decimal (e.g. 3.5) to a fraction (e.g. 7/2).
*
* @param float \$decimal the decimal number.
*
* @return array|bool a 1/2 would be [1, 2] array (this can be imploded with '/' to form a string)
*/
function decimalToFraction(\$decimal)
{
if (\$decimal < 0 || !is_numeric(\$decimal)) {
// Negative digits need to be passed in as positive numbers
// and prefixed as negative once the response is imploded.
return false;
}
if (\$decimal == 0) {
return [0, 0];
}

\$tolerance = 1.e-4;

\$numerator = 1;
\$h2 = 0;
\$denominator = 0;
\$k2 = 1;
\$b = 1 / \$decimal;
do {
\$b = 1 / \$b;
\$a = floor(\$b);
\$aux = \$numerator;
\$numerator = \$a * \$numerator + \$h2;
\$h2 = \$aux;
\$aux = \$denominator;
\$denominator = \$a * \$denominator + \$k2;
\$k2 = \$aux;
\$b = \$b - \$a;
} while (abs(\$decimal - \$numerator / \$denominator) > \$decimal * \$tolerance);

return [
\$numerator,
\$denominator
];
}
``````

Some Tests for it:

``````public function test_decimal_to_fraction_conversion()
{
\$this->assertEquals([0, 0], decimalToFraction(0));
\$this->assertEquals([1, 4], decimalToFraction(0.25));
\$this->assertEquals([1, 3], decimalToFraction(0.3333333333333));
\$this->assertEquals([1, 2], decimalToFraction(0.5));
\$this->assertEquals([1, 1], decimalToFraction(1));
\$this->assertEquals([6, 5], decimalToFraction(1.2));
\$this->assertEquals([1329, 997], decimalToFraction(1.333));
\$this->assertEquals([4, 3], decimalToFraction(1.3333));
\$this->assertEquals([3, 2], decimalToFraction(1.5));
\$this->assertEquals([2, 1], decimalToFraction(2));
\$this->assertEquals([7, 2], decimalToFraction(3.5));
\$this->assertEquals([PHP_INT_MAX, 1], decimalToFraction(PHP_INT_MAX));

\$this->assertFalse(decimalToFraction(-1));
\$this->assertFalse(decimalToFraction("string"));
}
``````

Photo by A. Levine

## 7 responses to “Converting a Decimal to a Fraction in PHP”

1. Kyle says:

well this simply doesnt work

its telling me that 1.5 = 3/3 instead of 3/2

1. Edd Turtle says:

Sorry about that Kyle (you were right). I’ve made a change which should work better.
e.g. 1.5=3/2 – 0.5=1/2 – 0.25=1/4 – 5=5/1

2. Josh says:

This is great, thanks. Anything we can do to eliminate wild crazy fractions like .38 that convert to 41/107?

1. Edd Turtle says:

Hi Josh, sure, you can change the \$tolerance to be more or less strict depending on what you’re after.

3. Mummy Ninja says:

What if I want 1.5 = 1 and 1/2 instead of 3/2? 😁

4. roydukkey says:

This test is wrong:

`\$this->assertEquals([1329, 997], decimalToFraction(1.333));`

If should be:

`\$this->assertEquals([1333, 1000], decimalToFraction(1.333));`

1. Edd Turtle says:

Hi, ye that is strange looking back on it. It’s not necessarily the fault of the test, it’s because the function does actually return 1329 and 997. I’ll need to review it to see if I can fix it.