0

I have this code that converts numbers into words. I found it on a website (I can't remember the site). The code often works well but in numbers whose tens are 1 or 0 get this error:

Notice: Undefined offset: 1 in C:\xampp\htdocs\...\printreceipt.php on line 103.

Also numbers after the decimal are not correct. I tried very hard to modify the code to solve the problem but I have not yet solved it. Also, I have found some questions in stakoverflow with same title but there is no such code, I tried to solve my problem from the answers of those questions.

Some results of my code:

154.000 = One Hundred Fifty Four Dollar.

615.000 = Notice: Undefined offset: 1 in .. Six Hundred Five Dollar/s

545.152 = Five Hundred Forty Five Dollar/s and Fifteen Sent This is the function code:

function numtowords($num){ 
$decones = array( 
            '01' => "One", 
            '02' => "Two", 
            '03' => "Three", 
            '04' => "Four", 
            '05' => "Five", 
            '06' => "Six", 
            '07' => "Seven", 
            '08' => "Eight", 
            '09' => "Nine", 
            10 => "Ten", 
            11 => "Eleven", 
            12 => "Twelve", 
            13 => "Thirteen", 
            14 => "Fourteen", 
            15 => "Fifteen", 
            16 => "Sixteen", 
            17 => "Seventeen", 
            18 => "Eighteen", 
            19 => "Nineteen" 
            );
$ones = array( 
            0 => " ",
            1 => "One",     
            2 => "Two", 
            3 => "Three", 
            4 => "Four", 
            5 => "Five", 
            6 => "Six", 
            7 => "Seven", 
            8 => "Eight", 
            9 => "Nine", 
            10 => "Ten", 
            11 => "Eleven", 
            12 => "Twelve", 
            13 => "Thirteen", 
            14 => "Fourteen", 
            15 => "Fifteen", 
            16 => "Sixteen", 
            17 => "Seventeen", 
            18 => "Eighteen", 
            19 => "Nineteen" 
            ); 
$tens = array( 
            0 => "",
            2 => "Twenty", 
            3 => "Thirty", 
            4 => "Forty", 
            5 => "Fifty", 
            6 => "Sixty", 
            7 => "Seventy", 
            8 => "Eighty", 
            9 => "Ninety" 
            ); 
$hundreds = array( 
            "Hundred", 
            "Thousand", 
            "Million", 
            "Billion", 
            "Trillion", 
            "Quadrillion" 
            ); //limit t quadrillion 
$num = number_format($num,2,".",","); 
$num_arr = explode(".",$num); 
$wholenum = $num_arr[0]; 
$decnum = $num_arr[1]; 
$whole_arr = array_reverse(explode(",",$wholenum)); 
krsort($whole_arr); 
$rettxt = ""; 
foreach($whole_arr as $key => $i){ 
    if($i < 20){ 
        $rettxt .= $ones[$i]; 
    }
    elseif($i < 100){ 
        $rettxt .= $tens[substr($i,0,1)]; 
        $rettxt .= " ".$ones[substr($i,1,1)]; 
    }
    else{ 
        $rettxt .= $ones[substr($i,0,1)]." ".$hundreds[0]; 
        $rettxt .= " ".$tens[substr($i,1,1)]; 
        $rettxt .= " ".$ones[substr($i,2,1)]; 
    } 
    if($key > 0){ 
        $rettxt .= " ".$hundreds[$key]." "; 
    } 

} 
$rettxt = $rettxt." Dollar/s";

if($decnum > 0){ 
    $rettxt .= " and "; 
    if($decnum < 20){ 
        $rettxt .= $decones[$decnum]; 
    }
    elseif($decnum < 100){ 
        $rettxt .= $tens[substr($decnum,0,1)]; 
        $rettxt .= " ".$ones[substr($decnum,1,1)]; 
    }
    $rettxt = $rettxt." Sent"; 
} 
return $rettxt;
} 

The error of tens 1 and 0 is in the following part:

else{ 
        $rettxt .= $ones[substr($i,0,1)]." ".$hundreds[0]; 
        $rettxt .= " ".$tens[substr($i,1,1)]; 
        $rettxt .= " ".$ones[substr($i,2,1)]; 
    }

and I think and I'm not sure, the error of the decimal is in the following lines:

if($decnum > 0){ 
    $rettxt .= " and "; 
    if($decnum < 20){ 
        $rettxt .= $decones[$decnum]; 
    }
    elseif($decnum < 100){ 
        $rettxt .= $tens[substr($decnum,0,1)]; 
        $rettxt .= " ".$ones[substr($decnum,1,1)]; 
    }
    $rettxt = $rettxt." Sent"; 
} 
  • Unless you really want to spend time fixing this buggy code for learning purpose, I suggest you use something more robust like the existing php [`NumberFormatter` class](https://www.php.net/manual/en/class.numberformatter.php) => `$f = new NumberFormatter("en-US", NumberFormatter::SPELLOUT); echo $f->format(615.000);` – Zeitounator Sep 21 '19 at 19:35
  • Your problem is that you split 615 to 6, 1, 5. Then you use 6 as hundreds, 1 as tens, but you don't have 1 defined in tens. What you should do is check is tens and ones are less than 20, then make is ones. Or just go with the advice above, numberformatter and it will solve all your problems – Andreas Sep 21 '19 at 20:02

1 Answers1

0
foreach ($whole_arr as $key => $i) {
    if ($i < 20) {
        $rettxt .= $ones[$i];
    } elseif ($i < 100) {
        $rettxt .= $tens[substr($i, 0, 1)];
        $rettxt .= " " . $ones[substr($i, 1, 1)];
    } else {
        $rettxt .= $ones[substr($i, 0, 1)] . " " . $hundreds[0]; //fix here
        if(substr($i, 1, 1) != 1){
            $rettxt .= " " . $tens[substr($i, 1, 1)];
            $rettxt .= " " . $ones[substr($i, 2, 1)];
        }
        else{
            $rettxt .= " " . $ones[substr($i, 0, 1)+9];
        }

    }
    if ($key > 0) {
        $rettxt .= " " . $hundreds[$key] . " ";
    }
}
Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125