english

learn php

learn css

learn html

learn javascript

learn php

7. functions

solution 7.4
3 minutes / 412 words

seven / solution 7.4

<?php

divide([58743758, 71]);

function divide($n, $maxDecimals = 5)
{
    // we'll use a global variable rather than passing one back and forth but that's an alternative approach
    global $result;
    // if we don't have any of our result built yet, initialize the variable as an empty string
    !isset($result) && ($result = "");
    print_r("dividing " . $n[0] . " by " . $n[1] . ".\n");
    // instead of working with decimals, just add the maximum amount of decimals to the end of the numerator and round it to no decimal places
    $top = round($n[0] * 10 ** $maxDecimals);
    $bottom = $n[1];
    // perform the recursive division
    doDivision($top, $bottom);
    // remove any extra decimal places then go back to decimal mode by dividing by the same number we multiplied by earlier to switch to integers
    $result = round($result) / 10 ** $maxDecimals;
    // if there are more decimal places in the real answer than we've calculated with long-division, let the user know
    !($n[0] / $n[1] == $result) && print_r("ran out of decimal places.\n");
    // output the result and return it
    print_r($n[0] . " divided by " . $n[1] . " is " . $result . "\n");
    return $result;
}

function doDivision($top, $bottom, $remainder = 0)
{
    global $result;
    // try dividing by the beginning of the numerator until the result is at least 1
    for ($i = 1; $i <= strlen($top); $i++) {
        // take $i digits from the beginning of the numerator (number of loops)
        $tryTop = substr($top, 0, $i);
        // check whether the denominator goes into the trial numerator at least once
        if ($tryTop / $bottom >= 1) {
            // round down
            $times = floor($tryTop / $bottom);
            // show how many times, making sure to use "once" instead of "1 times"
            $timesString = $times == 1 ? "once" : $times . " times";
            print_r($bottom . " goes into " . $tryTop + 0 . " " . $timesString);
            // calculate remainder using remainder division and output it
            $remainder = $tryTop % $bottom;
            $remainder && print_r(" with " . $remainder . " remaining");
            print_r(".\n");
            // add number of times to the end of our built result
            $result .= $times;
            // take the loop number of digits from the numerator because we've already dealt with those
            $top = substr($top, $i);
            // add the remainder back to the beginning of the numerator
            $remainder && ($top = $remainder . $top);
            // pass the rest of the numerator to this function for another pass and let it know if there's a remainder because that means skip the leading zero
            doDivision($top, $bottom, $remainder);
            return;
        } else {
            // if it's less than once, add a zero to the result we're building for each digit in the denominator
            // don't worry if it's at the beginning because leading zeros are trimmed from numeric values when we convert back
            !$remainder && ($result .= str_repeat("0", strlen($bottom)));
        }
    }
}

learn php

learn css

learn html

learn javascript

powered by akelei. an avi sato project.