2

I got a big problem solving this algorithm in PHP the idea is when :

  1. a user input is < 1000 (999) the output should be nine hundred and ninety-nine millimes
  2. when the user input is > 999 the output should be **one dinnar ** cause the dinnar is equal to 1000 millimes for example: if the input is 1,590 the output = one dinar and five hundred and ninety millimes another example if the input is 275,590 the output = two hundred and seventy-five dinars and five hundred and ninety millimes I write this code based on some article and I got a big error
<?php 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." dinar/s";

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

echo numtowords(275,590);



?>

the output here is Two Hundred Seventy Five dinar/s instead of two hundred and seventy-five dinars and five hundred and ninety millimes

Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
  • Is the *big error* that it did write "millimes" or is there another error message? – Uwe Dec 16 '22 at 14:31
  • Did this https://stackoverflow.com/questions/277569/is-there-an-easy-way-to-convert-a-number-to-a-word-in-php help with your problem. – Foobar Dec 16 '22 at 14:32
  • To debug var_dump($num) before and after the line `$num = number_format($num,2,".",","); - What do you get? ` – Uwe Dec 16 '22 at 15:06
  • I would advise you to put the number you want to print in a variable, before you pass it to the `numtowords ` function. For example: `$mynumber = 275,590;` and `numtowords($mynumber);` – Uwe Dec 16 '22 at 15:10
  • $num = 27.591; echo numtowords($num); Output Twenty Seven dinar/s and Fifty Nine FRANK/s – med amine eddine khadhraoui Dec 16 '22 at 15:26
  • Because you have Frank/s written in your code. Search and replace it. – Uwe Dec 16 '22 at 15:59
  • @Uwe replaced with what ? – med amine eddine khadhraoui Dec 16 '22 at 16:45
  • The unit you want? "millimes" – Uwe Dec 16 '22 at 17:53
  • And as you only get the text "Fifty Nine" ... that is because currency the script was written for, probably only had 1/100 units like dollar & cent as dinar & millimes has 1/1000 units. --> 100 cent make 1 dollar ... 1000 millimes make 1 dinar. ==> So the script needs to be adjusted for the part after the delimeter to handle values up to 999 millimes. **Maybe take a step back and try to understand, which part of your script handles what case.** – Uwe Dec 16 '22 at 18:04
  • @Uwe yes millimes and dinnar – med amine eddine khadhraoui Dec 16 '22 at 20:40

2 Answers2

0

When you put a comma "," in a function call it's considered as a parameters separator, so for the function numtowords(), you're passing two parameters not one 275 & 590:

echo numtowords(275,590);
___________________^

So it takes just 275 into consideration and ignores the second parameter since the function declaration is made to receive just one parameter $num.

The call must use the dot . instead :

echo numtowords(275.590); 
___________________^
Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
  • Yes i put a . And still the same results – med amine eddine khadhraoui Dec 16 '22 at 15:01
  • It would probably better to store the value in a Variable before passing it and not change the delimiter. As the mentioned change , changes the actual value in the currency. `275,590` is actually a thousand delimiter and correct is the use of your mentioned dot as a divider between dinar and millimes. But when you add a thousand delimiter to the example number, there would be a new issue. For example `1,275.590` would print out `1 Dinar` – Uwe Dec 16 '22 at 15:02
  • @medamineeddinekhadhraoui you should walk through your code and check, when your want to use a comma and/or a dot. - When you use a code snippet from another currency, be aware that delimters change and the code may not work as intended. – Uwe Dec 16 '22 at 15:05
  • I tried to pass the value in another variable and i changed the comma and it doesn’t work correctly – med amine eddine khadhraoui Dec 16 '22 at 15:29
  • If you apply the answer solution you'll get "Two Hundred Seventy Five dinar/s and Fifty Nine FRANK/s", which means the main problem is solved. – Zakaria Acharki Dec 16 '22 at 15:35
  • @ZakariaAcharki i tried what you told me and it seem the same problem – med amine eddine khadhraoui Dec 16 '22 at 15:41
  • @ZakariaAcharki when you apply the solution, the only thing which is solved, is that the full number and not only the part to the comma is used by the function. But still a wrong value is returned, as "Fifty Nine" is not the right value as well, as should be "five hundred ninety" FRANK/s (actually millimes). – Uwe Dec 16 '22 at 18:08
0

You can use the NumberFormatter class with the NumberFormatter::SPELLOUT flag. As a base:

$input = '275,590';
$arr = explode(',',$input);

$f = new NumberFormatter("en", NumberFormatter::SPELLOUT);
echo $f->format($arr[0]).' dinar and '.$f->format($arr[1]).' millimes ';
//two hundred seventy-five dinar and five hundred ninety millimes

Demo: https://3v4l.org/YR2WB

I have not dealt with the case distinctions. I think that's not the problem here.

jspit
  • 7,276
  • 1
  • 9
  • 17