Implementamos tecnologia y es asi como lo hacemos

Convertir Numeros a Letras en Java

Escrito el Septiembre 11, 2008 a las 2:30 PM por Camilo Nova

Hace rato que tenia esta clase y ahora que la necesito aprovecho para publicarla. Su funcionalidad es de convertir un numero a su representacion en letras

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/**
 * Esta clase provee la funcionalidad de convertir un numero representado en
 * digitos a una representacion en letras. Mejorado para leer centavos
 * 
 * @author Camilo Nova
 * @version 1.0
 */
public abstract class NumberToLetterConverter {
 
	private static final String[] UNIDADES = { "", "UN ", "DOS ", "TRES ",
			"CUATRO ", "CINCO ", "SEIS ", "SIETE ", "OCHO ", "NUEVE ", "DIEZ ",
			"ONCE ", "DOCE ", "TRECE ", "CATORCE ", "QUINCE ", "DIECISEIS",
			"DIECISIETE", "DIECIOCHO", "DIECINUEVE", "VEINTE" };
 
	private static final String[] DECENAS = { "VENTI", "TREINTA ", "CUARENTA ",
			"CINCUENTA ", "SESENTA ", "SETENTA ", "OCHENTA ", "NOVENTA ",
			"CIEN " };
 
	private static final String[] CENTENAS = { "CIENTO ", "DOSCIENTOS ",
			"TRESCIENTOS ", "CUATROCIENTOS ", "QUINIENTOS ", "SEISCIENTOS ",
			"SETECIENTOS ", "OCHOCIENTOS ", "NOVECIENTOS " };
 
	/**
	 * Convierte a letras un numero de la forma $123,456.32 (StoreMath)
	 * <p>
	 * Creation date 5/06/2006 - 10:20:52 AM
	 * 
	 * @param number
	 *            Numero en representacion texto
	 * @return Numero en letras
	 * @since 1.0
	 */
	public static String convertNumberToLetter(String number) {
		return convertNumberToLetter(StoreMath.parseString(number));
	}
 
	/**
	 * Convierte un numero en representacion numerica a uno en representacion de
	 * texto. El numero es valido si esta entre 0 y 999'999.999
	 * <p>
	 * Creation date 3/05/2006 - 05:37:47 PM
	 * 
	 * @param number
	 *            Numero a convertir
	 * @return Numero convertido a texto
	 * @throws NumberFormatException
	 *             Si el numero esta fuera del rango
	 * @since 1.0
	 */
	public static String convertNumberToLetter(double number)
			throws NumberFormatException {
		String converted = new String();
 
		// Validamos que sea un numero legal
		double doubleNumber = StoreMath.round(number);
		if (doubleNumber > 999999999)
			throw new NumberFormatException(
					"El numero es mayor de 999'999.999, "
							+ "no es posible convertirlo");
 
		String splitNumber[] = String.valueOf(doubleNumber).replace('.', '#')
				.split("#");
 
		// Descompone el trio de millones - ¡SGT!
		int millon = Integer.parseInt(String.valueOf(getDigitAt(splitNumber[0],
				8))
				+ String.valueOf(getDigitAt(splitNumber[0], 7))
				+ String.valueOf(getDigitAt(splitNumber[0], 6)));
		if (millon == 1)
			converted = "UN MILLON ";
		if (millon > 1)
			converted = convertNumber(String.valueOf(millon)) + "MILLONES ";
 
		// Descompone el trio de miles - ¡SGT!
		int miles = Integer.parseInt(String.valueOf(getDigitAt(splitNumber[0],
				5))
				+ String.valueOf(getDigitAt(splitNumber[0], 4))
				+ String.valueOf(getDigitAt(splitNumber[0], 3)));
		if (miles == 1)
			converted += "MIL ";
		if (miles > 1)
			converted += convertNumber(String.valueOf(miles)) + "MIL ";
 
		// Descompone el ultimo trio de unidades - ¡SGT!
		int cientos = Integer.parseInt(String.valueOf(getDigitAt(
				splitNumber[0], 2))
				+ String.valueOf(getDigitAt(splitNumber[0], 1))
				+ String.valueOf(getDigitAt(splitNumber[0], 0)));
		if (cientos == 1)
			converted += "UN";
 
		if (millon + miles + cientos == 0)
			converted += "CERO";
		if (cientos > 1)
			converted += convertNumber(String.valueOf(cientos));
 
		converted += "PESOS";
 
		// Descompone los centavos - Camilo
		int centavos = Integer.parseInt(String.valueOf(getDigitAt(
				splitNumber[1], 2))
				+ String.valueOf(getDigitAt(splitNumber[1], 1))
				+ String.valueOf(getDigitAt(splitNumber[1], 0)));
		if (centavos == 1)
			converted += " CON UN CENTAVO";
		if (centavos > 1)
			converted += " CON " + convertNumber(String.valueOf(centavos))
					+ "CENTAVOS";
 
		return converted;
	}
 
	/**
	 * Convierte los trios de numeros que componen las unidades, las decenas y
	 * las centenas del numero.
	 * <p>
	 * Creation date 3/05/2006 - 05:33:40 PM
	 * 
	 * @param number
	 *            Numero a convetir en digitos
	 * @return Numero convertido en letras
	 * @since 1.0
	 */
	private static String convertNumber(String number) {
		if (number.length() > 3)
			throw new NumberFormatException(
					"La longitud maxima debe ser 3 digitos");
 
		String output = new String();
		if (getDigitAt(number, 2) != 0)
			output = CENTENAS[getDigitAt(number, 2) - 1];
 
		int k = Integer.parseInt(String.valueOf(getDigitAt(number, 1))
				+ String.valueOf(getDigitAt(number, 0)));
 
		if (k <= 20)
			output += UNIDADES[k];
		else {
			if (k > 30 && getDigitAt(number, 0) != 0)
				output += DECENAS[getDigitAt(number, 1) - 2] + "Y "
						+ UNIDADES[getDigitAt(number, 0)];
			else
				output += DECENAS[getDigitAt(number, 1) - 2]
						+ UNIDADES[getDigitAt(number, 0)];
		}
 
		// Caso especial con el 100
		if (getDigitAt(number, 2) == 1 && k == 0)
			output = "CIEN";
 
		return output;
	}
 
	/**
	 * Retorna el digito numerico en la posicion indicada de derecha a izquierda
	 * <p>
	 * Creation date 3/05/2006 - 05:26:03 PM
	 * 
	 * @param origin
	 *            Cadena en la cual se busca el digito
	 * @param position
	 *            Posicion de derecha a izquierda a retornar
	 * @return Digito ubicado en la posicion indicada
	 * @since 1.0
	 */
	private static int getDigitAt(String origin, int position) {
		if (origin.length() > position && position >= 0)
			return origin.charAt(origin.length() - position - 1) - 48;
		return 0;
	}
 
}

8 Responses to “Convertir Numeros a Letras en Java”

  1. Anonimo Says:
    Noviembre 4th, 2008 at 9:23 AM

    Saludos Camilo Nova y gracias por el codigo fuente que publicaste. Ahora una pregunta porque tengo un problema con el source, ya que tiene un error con la variable “StoreMath” la cual nunca fue declarada y no encuentro de que clase instanciar a este objeto. La pregunta: De que tipo es el objeto “StoreMath” ???. Por otro lado, creo que quisiste con el metodo de la linea 33 [String convertNumberToLetter(String number)] invocar al metodo de la linea 51 [String convertNumberToLetter(double number)], pero creo que no va a funcionar porque en la implementacion del metodo de la linea 33 hace que este metodo se llame recursivamente puesto que el valor que recibes como parametro (String number) le aplicas un parseString (no se si se puede hacer esto a un String) invocandose a ella misma.

  2. Camilo Nova Says:
    Noviembre 4th, 2008 at 10:21 AM

    Hola Anonimo. StoreMath es una clase que me facilita algunas operaciones matematicas, puede ser facilmente reemplazada por Math u otra, no tiene ninguna funcionalidad especial.

    El metodo de la linea 33 recibe una cadena, mientras que el de la linea 55 recibe un ‘double’, la unica funcionalidad del metodo de la linea 33 es convertir la cadena en double y pasarselo al otro metodo, se hizo por efectos de portabilidad, de ninguna manera es una funcion recursiva, no se llama a ella misma.

    Saludos y gracias por comentar

  3. Anonimo Says:
    Noviembre 4th, 2008 at 11:03 AM

    Saludos Camilo, fijate en lo siguiente, en el metodo de la linea 33 recibes un String y lo vuelves a convertir en un String con el “parceString” que le haces al parametro de entrada, al menos que el metodo “parceString” que invocas sea una implementacion propia de tu clase StoreMath en donde se convierte un String a un Double (que seria un parceDouble). Te comento todo esto porque estoy probando la implementacion que posteaste pero no me funciona para ciertas cifras, como por ejemplo: 986956356, entendiendo que acepta numeros hasta 999999999. Camilo lo que pasa es que requiero una implementacion que me acepte cifras hasta 999999999.99 y estoy tratando de probar si con tu source puedo.
    Gracias por tu pronta respuesta.

  4. Camilo Nova Says:
    Noviembre 4th, 2008 at 11:06 AM

    Si mira, lo que pasa es que cuando recibia una cadena era de tipo como “123.456.789,00″ tenia un formato de localizacion, lo que hacia StoreMath era quitar esa localizacion y dejar el numero limpio para poderlo trabajar, si quieres no trabajes con el metodo que recibe una cadena, sino trabaja con el que recibe el double directamente.

  5. Anonimo Says:
    Noviembre 4th, 2008 at 11:24 AM

    Camilo fijate en lo siguiente, ingreso la cifra 816856968.25 (o cualquiera mayor a 9999999) y me da un error [La longitud maxima debe ser 3 digitos], he tratado de modificar el source para solucionar este problema pero todavia no he dado con la solucion. Si puedes por favor prueba y me indicas que resultado te dio.

    Te agradezco mucho la ayuda.

  6. Anonimo Says:
    Noviembre 4th, 2008 at 2:23 PM

    Ya se cual es el problema Camilo, y es el siguiente: cuando la cantidad excede de 9999999 los valores declarados tipo double pasan a notacion cientifica (Ej: 1.0856968E7) y el split es realizado mal… Estoy intentando solucionarlo…

  7. Camilo Nova Says:
    Noviembre 5th, 2008 at 7:16 AM

    muy buen punto, que bueno que ya lo solucionaste

  8. None Says:
    Diciembre 31st, 2008 at 3:04 PM

    Intenté utilizar el código para convertir un tipo “Double” (con centavos) a la representación en texto. Me convertía muy bien la cantidad a excepcion de los centavos, tuve que hacer la siguiente modificación:

    En el metodo “convertNumberToLetter(double number)” primero se redondea el numero Double enviado para verificar si se puede convertir, y posteriormente sobre ese numero redondeado se hacen las operaciones (por lo que se pierden los centavos en el redondeo)… la solucion es simplemente cambiar lo siguiente:
    * String splitNumber[] = String.valueOf(doubleNumber).replace(’.', ‘#’).split(”#”);
    por:
    * String splitNumber[] = String.valueOf(number).replace(’.', ‘#’).split(”#”);

    Saludos

Leave a Reply

AxiaCore Blog

Publicidad

Seguimiento

Etiquetas

Nosotros Leemos

Comentarios Recientes:

  • William: Hola. Muy buenos los apuntes. Estoy en el proceso de autoestudio con miras a la certificación CX-310-065 y...
  • None: Intenté utilizar el código para convertir un tipo “Double” (con centavos) a la representación en...
  • los harris: una página para niños y niñas para menores de 18 años, que haya mogollones de juegos divertidisimos y...
  • natali: bueno yo quiero saber como abrir mi propia pagina para que todos la vean ok…
  • hum: A mi se me queda sonando el bucle de audio bloqueado aunque reinicie asi…

Enlaces Recientes:

Archivo

Admin