# Converting a Decimal to a Fraction in PHP

16th October 2015
5 Comments
http://bit.ly/1OJrZ0r

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).
* Adapted from: http://jonisalonen.com/2012/converting-decimal-numbers-to-ratios/
*
* @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*

well this simply doesnt work

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

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

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

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

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