Tarea de programación Java: convertir números a texto

En este post escribiremos una clase de Java que nos permita convertir un número a su representación escrita en forma de texto. Existen algunas alternativas en español pero las que he revisado tienen límites muy pequeños como convertir sólo números entre 0 y 100, o tienen límites arbitrarios como 999,999,9991 sin ninguna razón aparente. Además, ya sabemos que me gusta hacer las cosas yo mismo 😛 . El código de este post puede convertir cualquier entero positivo de tipo int en el rango de 0 a 2,147,483,647 y, en teoría, cualquier número entero menor a 1,000,000,000,000 que debería ser suficiente en la mayoría de los casos 😛 :

package org.monstruosoft.utils;

// Para el formato de los números
import java.math.BigDecimal;
import java.math.BigInteger;

public class TareasProgramacion {

    /**
     * Convierte el número que recibe como argumento a su representación escrita con letra.
     *
     * @param s Una cadena de texto que contiene los dígitos de un número.
     * @return  Una cadena de texto que contiene la representación con letra de
     *          la parte entera del número que se recibió como argumento.
     */
    public static String cantidadConLetra(String s) {
        StringBuilder result = new StringBuilder();
        BigDecimal totalBigDecimal = new BigDecimal(s).setScale(2, BigDecimal.ROUND_DOWN);
        long parteEntera = totalBigDecimal.toBigInteger().longValue();
        int triUnidades      = (int)((parteEntera % 1000));
        int triMiles         = (int)((parteEntera / 1000) % 1000);
        int triMillones      = (int)((parteEntera / 1000000) % 1000);
        int triMilMillones   = (int)((parteEntera / 1000000000) % 1000);

        if (parteEntera == 0) {
            result.append("Cero ");
            return result.toString();
        }

        if (triMilMillones > 0) result.append(triTexto(triMilMillones).toString() + "Mil ");
        if (triMillones > 0)    result.append(triTexto(triMillones).toString());

        if (triMilMillones == 0 && triMillones == 1) result.append("Millón ");
        else if (triMilMillones > 0 || triMillones > 0) result.append("Millones ");

        if (triMiles > 0)       result.append(triTexto(triMiles).toString() + "Mil ");
        if (triUnidades > 0)    result.append(triTexto(triUnidades).toString());

        return result.toString();
    }

    /**
     * Convierte una cantidad de tres cifras a su representación escrita con letra.
     *
     * @param n La cantidad a convertir.
     * @return  Una cadena de texto que contiene la representación con letra
     *          del número que se recibió como argumento.
     */
    private static StringBuilder triTexto(int n) {
        StringBuilder result = new StringBuilder();
        int centenas = n / 100;
        int decenas  = (n % 100) / 10;
        int unidades = (n % 10);

        switch (centenas) {
            case 0: break;
            case 1:
                if (decenas == 0 && unidades == 0) {
                    result.append("Cien ");
                    return result;
                }
                else result.append("Ciento ");
                break;
            case 2: result.append("Doscientos "); break;
            case 3: result.append("Trescientos "); break;
            case 4: result.append("Cuatrocientos "); break;
            case 5: result.append("Quinientos "); break;
            case 6: result.append("Seiscientos "); break;
            case 7: result.append("Setecientos "); break;
            case 8: result.append("Ochocientos "); break;
            case 9: result.append("Novecientos "); break;
        }

        switch (decenas) {
            case 0: break;
            case 1:
                if (unidades == 0) { result.append("Diez "); return result; }
                else if (unidades == 1) { result.append("Once "); return result; }
                else if (unidades == 2) { result.append("Doce "); return result; }
                else if (unidades == 3) { result.append("Trece "); return result; }
                else if (unidades == 4) { result.append("Catorce "); return result; }
                else if (unidades == 5) { result.append("Quince "); return result; }
                else result.append("Dieci");
                break;
            case 2:
                if (unidades == 0) { result.append("Veinte "); return result; }
                else result.append("Veinti");
                break;
            case 3: result.append("Treinta "); break;
            case 4: result.append("Cuarenta "); break;
            case 5: result.append("Cincuenta "); break;
            case 6: result.append("Sesenta "); break;
            case 7: result.append("Setenta "); break;
            case 8: result.append("Ochenta "); break;
            case 9: result.append("Noventa "); break;
        }

        if (decenas > 2 && unidades > 0)
            result.append("y ");

        switch (unidades) {
            case 0: break;
            case 1: result.append("Un "); break;
            case 2: result.append("Dos "); break;
            case 3: result.append("Tres "); break;
            case 4: result.append("Cuatro "); break;
            case 5: result.append("Cinco "); break;
            case 6: result.append("Seis "); break;
            case 7: result.append("Siete "); break;
            case 8: result.append("Ocho "); break;
            case 9: result.append("Nueve "); break;
        }

        return result;
    }
}

Guarda el código anterior en un archivo con el nombre TareasProgramacion.java. Podemos usar la clase TareasProgramacion de la siguiente manera:

import java.util.Scanner;
import org.monstruosoft.utils.*;

public class Prueba {
    public static void main(String args[]) {
        Scanner s = new Scanner(System.in);

        do {
            System.out.println("Escribe un número entero: ");
            String n = s.nextLine();
            System.out.println(TareasProgramacion.cantidadConLetra(n));
        } while (true);
    }
}

Un ejemplo de la salida del programa anterior:

monstruosoft@monstruosoft-PC:~$ java Prueba 
Escribe un número entero: 
10
Diez 
Escribe un número entero: 
2874
Dos Mil Ochocientos Setenta y Cuatro 
Escribe un número entero: 
19349817243
DieciNueve Mil Trescientos Cuarenta y Nueve Millones Ochocientos DieciSiete Mil Doscientos Cuarenta y Tres 
Escribe un número entero:

He creado un repositorio de github con el código de este post. Puedes descargar el código haciendo click aquí.

Debería ser sencillo modificar este código para aceptar números negativos o convertir cantidades en el rango de billones o miles de billones pero lo dejo como ejercicio al lector 😛 .


Referencias:

https://github.com/Axiacore/numero-a-letras

One comment

  1. ¡Eres un crack! Muchas gracias, tu código me fue de mucha ayuda y aprendí mucho también

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s