post

Convertir números a letras

convertir números a letras black typewriter
Photo by Dominika Roseclay on Pexels.com

Convertir números a letras, suele ser un ejercicio muy peculiar en el tema de la programación, el detalle esta en los primeros 19 números de la numeración ya que a partir del 20 hasta el infinito no es más que la conjugación de estos. A continuación se describe la función que se desarrollo:

Código fuente

function convertirNumeroALetras($numero) {
    # arreglo con los nombres de los números del 0 al 19
    $numerosHastaDiecinueve = array(
        0 => 'un', 1 => 'uno', 2 => 'dos', 3 => 'tres', 4 => 'cuatro', 5 => 'cinco',
        6 => 'seis', 7 => 'siete', 8 => 'ocho', 9 => 'nueve', 10 => 'diez', 11 => 'once',
        12 => 'doce', 13 => 'trece', 14 => 'catorce', 15 => 'quince', 16 => 'dieciséis',
        17 => 'diecisiete', 18 => 'dieciocho', 19 => 'diecinueve'
    );

    # arreglo con los nombres de las decenas
    $decenas = array(
        20 => 'veinte', 30 => 'treinta', 40 => 'cuarenta', 50 => 'cincuenta',
        60 => 'sesenta', 70 => 'setenta', 80 => 'ochenta', 90 => 'noventa'
    );

    # arreglo con los nombres de las centenas
    $centenas_letras = array(
        100 => 'cien', 200=> 'docientos', 300=>'trecientos', 400=>'cuatrocientos', 500=>'quinientos',
        600=>'seicientos', 700=>'setecientos', 800=>'ochocientos', 900=>'novecientos', 1000 => 'mil'
    );


    if ($numero < 20) {
        # Si el número es menor que 20, se busca en el array de números hasta diecinueve
        if($numero == 00){
            #break;
        }else{
            return $numerosHastaDiecinueve[$numero];
        }
    }elseif ($numero < 100 ) {
        # Si el número es menor que 100, se descompone en decenas y unidades
        $decena = floor($numero / 10) * 10;
        $unidad = $numero % 10;
        $letra = $decenas[$decena];
        if ($unidad > 0) {
            $letra .= ' y ' . $numerosHastaDiecinueve[$unidad];
        }
        return $letra;
    } elseif ($numero < 1000) {
        # Si el número es menor que 1000, se descompone en centenas, decenas y unidades
        $centena = floor($numero / 100);
        $resto = $numero % 100;
        $centena = floor($numero / 100)*100;
        $decena = $numero - $centena;
        $letra = ($numero < 200 && $numero > 100) ? $centenas_letras[$centena].'to '.convertirNumeroALetras($decena) : $centenas_letras[$centena].' '.convertirNumeroALetras($decena);
        return $letra;
    } else {
        # Si el número es mayor o igual a 1000, se descompone en miles, centenas, decenas y unidades
        $millar = floor($numero / 1000);
        $resto = $numero % 1000;
        $letra = $millar == 1 ? $centenas_letras[1000] : convertirNumeroALetras($millar) . ' mil';
        # si el número es mayor de 100 y menor a los 102, ciento un mil ... y no ciento uno mil...
        if( ($millar >100 && $millar <102)){
            $letra = $centenas_letras[$millar-1].'to '.$numerosHastaDiecinueve[0].' mil ';
        }
        # validaciones para los 201, 301, 401, ... 901 los docientos ... un mil 
        if(($millar > 200 && $millar < 202) || ($millar > 300 && $millar < 302) || ($millar > 400 && $millar < 402) || ($millar > 500 && $millar < 502) || ($millar > 600 && $millar < 602) || ($millar > 700 && $millar < 702) || ($millar > 800 && $millar < 802) || ($millar > 900 && $millar < 902)){
            $letra = $centenas_letras[$millar-1].' '.$numerosHastaDiecinueve[0].' mil ';
        }
        if ($resto > 0) {
            $letra .= ' ' . convertirNumeroALetras($resto);
        }
       # si el número es menor o igual a 1'000,000, se descompone en los millares, miles, centenas, decenas y unidades.
        if ($numero == 1000000){
            $letra =  $numerosHastaDiecinueve[0].' millón';
        }elseif ($numero > 1000000){
            $millon = floor($numero / 1000000);
            $centimas = $numero - (1000000*$millon);
            if ($millon == 1){
                $letra = $numerosHastaDiecinueve[0].' millón '.convertirNumeroALetras($centimas);
            }else{
                $letra = convertirNumeroALetras($millon).' millones '.convertirNumeroALetras($centimas);
                #$letra = $centimas;
            }
        }
        return $letra;
    } 
}

Explicando la función

Primero hay que tener en cuenta que la se creo tres grupos de arreglos donde se encuentren los que no son compuestos, las decenas y centenas; el resto de los números son el resultado de la composición o mezcla de estos tres arreglos. Los arreglos son:

  • numerosHastaDiecinueve: Este arreglo contiene todos los números desde el uno hasta el 19, también cuenta con una posición donde esta la palabra “un” este es usado para referirse a las cantidades del millón, es decir, no suele escribirse uno millón, sino un millón.
  • decenas: Este arreglo contiene todas las descripciones que se pueda tener en el orden de las decenas.
  • centenas_letras: Este arreglo contiene las descripciones que se puede tener en el orden de las centenas.

Cuando se recibe una cantidad la función la procesa, identificando todos los números menores a 20 (los que se encuentran en el primer arreglo). Si esta condición se cumple ( if ($number < 20) ) se valida que la cantidad que se envía no sea igual a cero, de ser así se envía el contenido que tiene el arreglo en la posición de la cantidad dada; así al recibir la cantidad 11, 10, 1 o cualquiera que sea menor a veinte escribirá once, diez, uno o lo que contenga la casilla en esa posición.

Luego se usa la condición $numero < 100 para descomponer las decenas y si el número llega a ser menor de 20 se concatena con el llamado a la función usando la recursividad para los unidades y así componer la descripción de la cantidad.

Para el caso de las centenas se sigue la misma regla solo que ahora la condición es para cuando $numero < 1000, se tiene el caso de que las cantidades sea 101, 201, que debe escribir un y no uno, para ello se agrego en la posición cero del arreglo numerosHastaDiecinueve, la notación un, que también se utilizará cuando se este en el rango de los millones, se escribirá un millón. Sin esta variante se escribiría uno millón o ciento uno mil.

Ejecución del script

Imagen 1. Conversión de números a letras. Fuente: tumblr.com
Vídeo 1. Se muestra la ejecución del script. Fuente: youtube.com

Se puede apreciar en la imagen 1, el resultado que se tiene al ejecutar el script en el rango de los millones. Mientras en el vídeo 1, se observa como el script puede ser modificado para convertir diferentes tipos de cantidades.

Este script permite convertir números a letras hasta el orden de los millones, faltaría agregar las correspondientes líneas para billones, trillones y demás. Si se utilizar en algún sistema de presupuestos o facturación solo hay que cambiar en el contenido uno del array numerosHastaDiesinueve por un, y posteriormente concatenarlo con las palabras “Pesos M.N.”.

Versión en ingles

Código fuente disponible en el github

Leave a Reply

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