[Pugged] Whoohoo!!

Renegade Muskrat ciapug@ciapug.org
Sun, 01 Sep 2002 21:52:08 -0500


>Here it is.... Ok, so this is a first.... First time I've ever posted
>any code as an actual "real" programmer.  Be gentle!
>
>All you need to do is send a number to numto_word and it will return the
>text.

I didn't try your version. But it inspired me to write my own. I wrote it
quickly so it might not be as optimized as possible. But i've included it
below. It even adds the hyphen for numbers from 21 to 99.



<?php

// This code written by Dan Ramaley. 2002-09-01. No warranties expressed
// or implied. Use at your own risk.

// Function that takes a number and returns the text of the number if it
// were to be written out. The text returned is in the American style.
// It would not take much to modify the function to return British
// numbers however--change the 3 in the main loop to a 6, and modify the
// small number handler to go up to 999,999 rather than just 999 and
// that should be close.
//
// Do not throw numbers in the quintillions or higher at this function.
// It was written with number in the quadrillions in mind and no higher.
// If the number can be represented by a PHP integer as of PHP 4.2, then
// it should be safe.
function num2text($number) {
    // Lookup table of digit group names. Don't bother going beyond
    // quadrillion since PHP doesn't seem to support such large numbers
    // at full precision.
    $group = array("", "thousand", "million", "billion", "trillion",
                   "quadrillion");

    // Make sure we're dealing with a positive number.
    if ($number < 0) {
        $result = "negative ";
        $number = abs($number);
    }

    // Now make sure the number isn't a fraction.
    $number = floor($number);

    // First handle numbers less than 1000 so we can use it recursively.
    if ($number < 1000) {
        // Set up some lookup tables of values.
        $ones = array("zero", "one", "two", "three", "four", "five",
                      "six", "seven", "eight", "nine", "ten", "eleven",
                      "twelve", "thirteen", "fourteen", "fifteen",
                      "sixteen", "seventeen", "eighteen", "nineteen");
        $tens = array("twenty", "thirty", "forty", "fifty", "sixty",
                      "seventy", "eighty", "ninety");
        // Process the hundreds
        $hundreds_digit = floor($number / 100);
        if ($hundreds_digit) {
            $result .= $ones[$hundreds_digit] . " hundred ";
            $number -= $hundreds_digit * 100;
        }
        // Now process the tens
        $tens_digit = floor($number / 10);
        if ($tens_digit > 1) {
            $number -= $tens_digit * 10;
            $result .= $tens[$tens_digit - 2] . ($number ? "-" : " ");
        }
        // And then process whatever is left.
        if ($number or !$result) {
            $result .= $ones[$number] . " ";
        }
        return rtrim($result);
    }

    // Loop through digit groupings
    for ($i = sizeof($group) - 1; $i >= 0; $i--) {
        $base = pow(10, 3 * $i);
        if ($number >= $base) {
            $val = floor($number / $base);
            $result .= num2text($val) . " " . $group[$i] . " ";
            $number -= $val * $base;
        }
    }

    return rtrim($result);
}


// Quick demo of the function above. If you actually run this as is
// you'll get a rather large result. You have been warned. If you want
// to see a more resonably sized demo, change 1000000 to 100.
for ($bottles = 1000000; $bottles > 0; $bottles--) {
    echo num2text($bottles) . " bottle" . (($bottles > 1) ? "s" : "") .
        " of beer on the wall<br>\n";
    echo num2text($bottles) . " bottle" . (($bottles > 1) ? "s" : "") .
        " of beer<br>\n";
    echo "Take one down, pass it around<br>\n";
    echo num2text($bottles - 1) . " bottle" . (($bottles != 2) ? "s" :
        "") . " of beer on the wall.<br>\n";
    echo "<br>\n";
}

?>

                                               -- Dan
  --------------------------------------------------------------------
            "I'm still sane on three planets and two moons."
  --------------------------------------------------------------------
      Daniel Ramaley                  3118 Cottage Grove Ave Apt 8
      dramaley at spatulacity dot cx        Des Moines, Iowa 50311
      http://www.spatulacity.cx/                    (515) 271-5233
  --------------------------------------------------------------------
       WARNING: REDISTRIBUTION OF THIS MESSAGE MAY BE IN
                VIOLATION OF APPLICABLE COPYRIGHT LAWS.
                THIS MESSAGE NOT GUARANTEED Y-TO-K COMPLIANT.