Esta clase de actionscript 3 sirve para expresar un número con palabras. La api de esta clase se compone de 2 métodos estáticos llamados convertNumber y convertString, que reciben 2 parámetros:
- Un número de tipo Number (convertNumber) ó un String (convertString), que será el número que queremos convertir. Acepta valores negativos, decimales (Ej: 1.818), y exponenciales (Ej: 1.1e99).
- Un String que nos indicará el género del número devuelto (sólo veremos su efecto en las terminaciones de las centenas, y si el número acaba en 1, en cuyo caso devolverá "uno", "una" o "un" dependiendo del valor de este string). Este parámetro tiene 3 posibles valores, dados por las constantes estáticas de la propia clase NumberToWords GENDER_FEMALE, GENDER_MALE y GENDER_NONE.
La diferencia entre ambos métodos es que si usamos un Number, a partir de las centenas de trillón el número devuelto estará en formato exponencial, a partir del exponente 308 se considerará que el número es infinito, y además se hará un redondeo cuando el número tenga demasiados decimales.
Sin embargo si usamos convertString (usando un String en lugar de un número), se convertirá el número tal y como esté representado en la cadena de texto que introduzcamos, sin límite (aunque si introducimos más de 1000 cifras el cálculo se ralentiza un poco). A partir de las 100 cifras el número se interpretará como múltiplos de gúgol.
Ejemplo de uso:
Código :
import NumberToWords; var number:Number = 21; var strNumber:String = "80000000000000000000900000000000000000000000000000000000000000008000000000000000000000000000000000000000001"; trace(NumberToWords.convertNumber(number, NumberToWords.GENDER_FEMALE)); //veintiuna trace(NumberToWords.convertNumber(number, NumberToWords.GENDER_NONE)); //veintiún trace(NumberToWords.convertString(strNumber, NumberToWords.GENDER_MALE)); //ocho millones de gúgoles novecientos tetradecallones ocho septillones uno
En el siguiente swf se puede comprobar el funcionamiento de la clase. Hay que introducir el número a convertir en el TextArea superior, y en el inferior lo veremos expresado con palabras. Pulsando el botón “Abc” cambiamos el método que se utilizará para convertir el número (convertNumber o convertString), y con el otro botón cambiamos el género.
Código de la clase:
Código :
package
{
public class NumberToWords
{
public static const GENDER_FEMALE:String = "genderFemale";
public static const GENDER_MALE:String = "genderMale";
public static const GENDER_NONE:String = "genderNone";
private static const UNITS:Array = ["cero", "un", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve"];
private static const TENS:Array = ["", "diez", "veinte", "treinta", "cuarenta", "cincuenta", "sesenta", "setenta", "ochenta", "noventa"];
private static const TEN_TO_TWELVE:Array = ["", "once", "doce", "trece", "catorce", "quince", "dieciséis", "diecisiete", "dieciocho", "diecinueve"];
private static const TWELVE_TO_THIRTY:Array = ["", "", "veintidós", "veintitrés", "veinticuatro", "veinticinco", "veintiséis", "veintisiete", "veintiocho", "veintinueve"];
private static const HUNDREDS:Array = ["", "cient", "doscient", "trescient", "cuatrocient", "quinient", "seiscient", "setecient", "ochocient", "novecient"];
private static const MILLIONS:Array = ["", "mill", "bill", "trill", "cuatrill", "quintill", "sextill", "septill", "octill", "nonill",
"decall", "undecall", "dodecall", "tridecall", "tetradecall", "pentadecall", "hexadecall"];
private static var wordsArray:Array;
public static function convertNumber(number:Number, gender:String):String
{
//En caso de que no sea un número válido:
if (isNaN(number)) return "No es un número";
//Si el número es mayor que 1.79e+308 se considera infinito:
if (number == Infinity) return "Infinito";
//Llama a toWords para resolverlo convertido en String:
return toWords(number.toString(), gender);
}
public static function convertString(inStr:String, gender:String):String
{
//En caso de que no sea un número válido:
if (isNaN(Number(inStr))) return "No es un número";
return toWords(inStr, gender);
}
private static function toWords(inStr:String, gender:String):String
{
//Vaciamos el array que irá guardando los resultados:
wordsArray = [];
var integerPart:String;
var decimalPart:String;
var exponentPart:String;
//Divido el texto del número en las partes entera, decimal y exponencial:
var splittedArray:Array = inStr.split("e");
if (splittedArray.length == 2) exponentPart = splittedArray[1];
splittedArray = splittedArray[0].split(".");
if (splittedArray.length == 2) decimalPart = splittedArray[1];
integerPart = splittedArray[0];
//Resuelve la parte entera:
solveIntegerPart(integerPart, gender);
//Resuelve la parte decimal si la hay:
if (decimalPart != null)
{
wordsArray.push("coma");
solveDecimalPart(decimalPart);
}
//Resuelve la parte exponencial si la hay:
if (exponentPart != null)
{
wordsArray.push("por diez elevado a la");
wordsArray.push(solveIntegerPart(exponentPart, NumberToWords.GENDER_MALE));
}
//Devuelve los elementos del array unidos por espacios:
return wordsArray.join(" ");
}
private static function solveDecimalPart(inStr:String):void
{
for (var i:uint = 0;i < inStr.length; i++)
{
//Los decimales siempre en masculino:
solveUnits(inStr.charAt(i), NumberToWords.GENDER_MALE);
}
}
private static function solveIntegerPart(inStr:String, gender:String):void
{
//Si el número es negativo, se añade menos al array y se convierte en valor absoluto:
if (inStr.charAt(0) == "-")
{
wordsArray.push("menos");
inStr = inStr.slice(1);
}
//Si el String comienza por "+" lo quitamos:
if (inStr.charAt(0) == "+") inStr = inStr.slice(1);
//Si el número es 0:
if (Number(inStr) == 0)
{
wordsArray.push(UNITS[0]);
return;
}
//Se resuelve el número natural resultante:
solveNaturalPart(inStr, gender);
}
private static function solveNaturalPart(inStr:String, gender:String):void
{
//Esta función resolverá recursivamente las diferentes partes del número natural
//Elimina todos los ceros a la izquierda:
while(inStr.charAt(0) == "0")
{
inStr = inStr.slice(1);
}
//Si todo eran 0 sale de la función
if (inStr == "") return;
var integerLength:Number = inStr.length;
if (integerLength > 100)
solveGoogols(inStr, gender);
else if (integerLength > 6)
solveMillions(inStr, gender);
else if (integerLength > 3)
solveThousands(inStr, gender);
else if (integerLength > 2)
solveHundreds(inStr, gender);
else if (integerLength > 1)
solveTens(inStr, gender);
else
solveUnits(inStr, gender);
}
private static function solveGoogols(inStr:String, gender:String):void
{
var quotient:String = inStr.slice(0, -100);
var remainder:String = inStr.slice(-100);
//Para gúgoles el género es neutro:
solveNaturalPart(quotient, NumberToWords.GENDER_NONE);
//Si el cociente es 1 se usa gúgol y si no gúgoles:
if (uint(quotient) == 1)
{
wordsArray.push("gúgol");
}
else
{
//Si los 6 dígitos anteriores a los gúgoles son 0, añade "de":
if (quotient.length > 6 && uint(quotient.slice(-6)) == 0)
{
wordsArray.push("de");
}
wordsArray.push("gúgoles");
}
solveNaturalPart(remainder, gender);
}
private static function solveMillions(inStr:String, gender:String):void
{
var millionIndex:uint = Math.floor((inStr.length - 1) / 6);
var quotient:String = inStr.slice(0, -millionIndex * 6);
var remainder:String = inStr.slice(-millionIndex * 6);
//Para iguales o superiores al millón, el género es neutro, porque se refiere al millón y no a lo que estemos contando:
solveNaturalPart(quotient, NumberToWords.GENDER_NONE);
//Si el cociente es 1 se usa la terminación en singular y si no en plural:
if (uint(quotient) == 1)
{
wordsArray.push(MILLIONS[millionIndex] + "ón");
}
else
{
wordsArray.push(MILLIONS[millionIndex] + "ones");
}
solveNaturalPart(remainder, gender);
}
private static function solveThousands(inStr:String, gender:String):void
{
var quotient:String = inStr.slice(0, -3);
var remainder:String = inStr.slice(-3);
if (uint(quotient) > 1)
{
//El género femenino se trata de forma diferente al masculino y neutro:
if (gender == NumberToWords.GENDER_MALE)
{
solveNaturalPart(quotient, NumberToWords.GENDER_NONE);
}
else
{
solveNaturalPart(quotient, gender);
}
}
wordsArray.push("mil");
solveNaturalPart(remainder, gender);
}
private static function solveHundreds(inStr:String, gender:String):void
{
var quotient:String = inStr.slice(0, -2);
var remainder:String = inStr.slice(-2);
//Si es 100 exacto devuelve cien:
if (uint(inStr) == 100)
{
wordsArray.push("cien");
return;
}
//En los demás casos:
var suffix:String;
if (uint(quotient) == 1)
{
//Si está entre 101 y 199 devuelve "ciento":
suffix = "o";
}
else
{
//Si no devuelve doscientos/as, trescientos/as, ...
suffix = (gender == NumberToWords.GENDER_FEMALE) ? "as" : "os";
}
wordsArray.push(HUNDREDS[uint(quotient)] + suffix);
solveNaturalPart(remainder, gender);
}
private static function solveTens(inStr:String, gender:String):void
{
var quotient:String = inStr.slice(0, -1);
var remainder:String = inStr.slice(-1);
//21 tendrá diferentes valores según el género:
if (uint(inStr) == 21)
{
switch (gender)
{
case NumberToWords.GENDER_FEMALE:
wordsArray.push("veintiuna");
break;
case NumberToWords.GENDER_MALE:
wordsArray.push("veintiuno");
break;
case NumberToWords.GENDER_NONE:
wordsArray.push("veintiún");
break;
}
return;
}
//Si el residuo es 0 devuelve diez, veinte, treinta, ...
if (uint(remainder) == 0)
{
wordsArray.push(TENS[uint(quotient)]);
return;
}
//Si el cociente es 1 devuelve once, doce, trece, ...
if (uint(quotient) == 1)
{
wordsArray.push(TEN_TO_TWELVE[uint(remainder)]);
return;
}
//Si el cociente es 2 devuelve veintidós, veintitrés, ... (el caso de 21 ya se ha tratado más arriba)
if (uint(quotient) == 2)
{
wordsArray.push(TWELVE_TO_THIRTY[uint(remainder)]);
return;
}
//En el resto de los casos:
wordsArray.push(TENS[uint(quotient)]);
wordsArray.push("y");
solveNaturalPart(remainder, gender);
}
private static function solveUnits(inStr:String, gender:String):void
{
var returnedStr:String = UNITS[uint(inStr)];
if (uint(inStr) == 1) returnedStr += getGenderSuffix(gender);
wordsArray.push(returnedStr);
}
private static function getGenderSuffix(gender:String):String
{
if (gender == NumberToWords.GENDER_FEMALE) return "a";
if (gender == NumberToWords.GENDER_MALE) return "o";
return "";
}
}
}
¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

gracias por compartirla