Converting a Decimal to a Fraction in PHP

Converting a Decimal to a Fraction in PHP

   4 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

4 responses to “Converting a Decimal to a Fraction in PHP

Leave a Reply

Your email address will not be published. Required fields are marked *