Conversor de números a texto en inglés
Abstract
Desarrollo de un servicio web para convertir números a texto en inglés. Dado un número, se obtienen distintos resultados alternativos de su conversión a texto : en cardinal, ordinal, escala corta, escala larga, etc.
Full text
Trabajo de Fin de Grado Conversor de números a texto en inglés Autor Néstor Pulido Robaina Tutor Francisco Javier Carreras Riudavets Profesor del Departamento de Informática y Sistemas
ÍNDICE 1. ESTADO ACTUAL Y OBJETIVOS. ............................................................................................. 4 1.1. Conceptos generales sobre la conversión de números a texto en inglés. .................... 4 1.1.1. Números cardinales. ............................................................................................ 4 1.1.2. Números ordinales. ............................................................................................. 9 1.1.3. Números fraccionales. ....................................................................................... 11 1.1.4. Números decimales. .......................................................................................... 12 1.1.5. Números negativos. ........................................................................................... 15 1.1.6. Nombres de números largos. ............................................................................ 15 1.1.7. Números especiales. .......................................................................................... 18 1.2. Normas para decidir si escribimos dígitos o palabras. ................................................ 22 1.3. Objetivos a cubrir en este trabajo. .............................................................................. 25 2. JUSTIFICACIÓN DE LAS COMPETENCIAS ESPECÍFICAS CUBIERTAS. ..................................... 26 2.1. Trabajo de fin de grado. .............................................................................................. 26 2.2. Comunes a la ingeniería informática........................................................................... 26 2.3. Ingeniería del Software. .............................................................................................. 27 2.4. Sistemas de información. ............................................................................................ 27 2.5. Tecnologías de la información. ................................................................................... 28 3. APORTACIONES. .................................................................................................................. 28 4. REQUISITOS E INSTALACIÓN. .............................................................................................. 30 5. DISEÑO. ............................................................................................................................... 31 5.1. Entrada y salidas del proceso. ..................................................................................... 31 5.1.1. Entrada. .............................................................................................................. 32 5.1.2. Salidas. ................................................................................................................ 33
5.1.3. Tipos de resultados. ........................................................................................... 34 5.2. Vista general del proceso de conversión. ................................................................... 36 5.3. Estructura de la clase Conversor. ................................................................................ 39 5.3.1. Clase Res_Par. ..................................................................................................... 41 5.3.2. Clase Res_Def. ..................................................................................................... 42 5.3.3. Definiciones de tipos. ........................................................................................ 49 5.3.4. Variables globales. ............................................................................................. 49 5.3.5. Funciones locales. .............................................................................................. 50 5.3.6. Métodos. ............................................................................................................. 55 6. DESARROLLO. ...................................................................................................................... 56 6.1. Programación orientada a objetos. ............................................................................. 56 6.2. Expresiones regulares. ................................................................................................ 57 6.3. Concurrencia. .............................................................................................................. 58 6.4. Fraccionamiento y concatenación. ............................................................................. 61 6.5. Construcción dinámica de términos con prefijos y sufijos. ......................................... 65 6.6. Integración de resultados............................................................................................ 68 6.7. Mejora de rendimiento a través de la clase StringBuilder. ......................................... 70 7. CONCLUSIONES Y TRABAJOS FUTUROS. ............................................................................. 71 8. FUENTES DE INFORMACIÓN. ............................................................................................... 71
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 4 de 72 1. ESTADO ACTUAL Y OBJETIVOS. Este trabajo consiste en la implementación de un servicio web de conversión de números a texto en el idioma inglés. Normalmente, tendemos a escribir números mediante dígitos, especialmente cuando se trata de números grandes, pero existen normas por las cuales, en determinadas circunstancias, se hace necesario sustituir dígitos por palabras. Pero antes de comentar dichas normas, procederemos a explicar los conceptos generales que describen la formación de números mediante palabras. 1.1. Conceptos generales sobre la conversión de números a texto en inglés. Como ocurre en el idioma español, la conversión de números a texto en inglés resulta un proceso sistemático, aunque con algunas excepciones, que puede obtener distintos resultados alternativos. Así, un número puede ser escrito en forma cardinal, ordinal, fraccionaria…, y en determinados contextos puede se escrito con palabras ajenas al ámbito de la numeración, como por ejemplo “century” para referirse a 100 años (un siglo). A continuación describiremos las formas más usadas de escribir un número en inglés. 1.1.1. Números cardinales. Los números cardinales expresan cantidades. Del 0 al 19 se escriben según la siguiente tabla: 0 Zero 10 Ten 1 One 11 Eleven 2 Two 12 Twelve 3 Three 13 Thirteen 4 Four 14 Fourteen 5 Five 15 Fifteen 6 Six 16 Sixteen 7 Seven 17 Seventeen 8 Eight 18 Eighteen 9 Nine 19 Nineteen Tabla T.1.1.1.A
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 5 de 72 Como se puede apreciar, a partir del número 16 se escribe indicando las unidades seguido de la palabra “teen”, eliminando la doble “t” en el caso del número 18 (eightteen = eighteen). A partir de 20, las decenas se escriben según la siguiente tabla: 20 Twenty 60 Sixty 30 Thirty 70 Seventy 40 Forty 80 Eighty 50 Fifty 90 Ninety Tabla T.1.1.1.B Obsérvese también como a partir de 60, las decenas se escriben como las unidades pero seguido de la terminación “ty”, eliminando la doble “t” en el caso de 80 (eightty = eighty). Si el número está entre 21 y 99, y el dígito de unidades no es cero, se escribe normalmente como dos palabras separadas por un guión (decenasunidades): 21 Twenty-one 25 Twenty-five 32 Thirty-two 58 Fifty-eight 64 Sixty-four 79 Seventy-nine 83 Eighty-three 99 Ninety-nine Tabla T.1.1.1.C Las centenas son regulares (salvo el hecho de que la palabra “hundred” se mantiene en singular independientemente del número que la preceda): 100 One hundred 125 One hundred twenty-five 200 Two hundred 584 Five hundred eighty-four … … … … 900 Nine hundred 731 Seven hundred thirty-one Tabla T.1.1.1.D Lo mismo ocurre con los millares, donde el número de miles va seguido de la palabra “thousand”: 1.000 one thousand 20.000 twenty thousand 2.000 two thousand 21.000 twenty-one thousand 10.000 ten thousand 30.000 thirty thousand 11.000 eleven thousand 85.000 eighty-five thousand Tabla T.1.1.1.E
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 6 de 72 Llegados a este punto, hay que decir que existen diferencias entre el inglés británico y el inglés americano a la hora de escribir números. En inglés americano, los números de cuatro dígitos con centenas distintas de cero suelen nombrarse usando múltiples “hundred” combinadas con decenas y unidades, por ejemplo: 1001: "One thousand one" 1103: "Eleven hundred three" 1225: "Twelve hundred twenty-five" 4042: "Four thousand forty-two" 9999: "Ninety-nine hundred ninety-nine." En inglés británico, este estilo es común para múltiplos de 100 entre 1000 y 2000, por ejemplo 1500 como “fifteen hundred”, pero no para números más grandes. En determinados contextos, los americanos pueden pronunciar números de cuatro dígitos con decenas distintas de cero y unidades como pares de números de dos dígitos sin decir “hundred” e insertando la palabra “oh” para las decenas con cero, por ejemplo: 2659: "twenty-six fifty-nine" 4105: "forty-one oh five" Probablemente, este uso ha evolucionado a partir del uso para indicar años, por ejemplo, "nineteen eighty-one" (1981). Se evita para números menores de 2500 si el contexto puede generar confusión con la hora del día: “ten ten” o “twelve oh four”. También puede llegar a usarse en un contexto económico dónde se espera que haya parte decimal, por ejemplo al indicar el precio de un artículo. Los números intermedios se leen de forma diferente dependiendo de su uso. La forma típica de nombrarlos se da cuando los números son usados para contar. Otra forma es cuando se usan como etiquetas. La siguiente tabla muestra distintas alternativas:
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 7 de 72 Inglés británico coloquial Inglés americano coloquial Inglés británico coloquial (normalmente no usado en América) "How many marbles do you have?" "What is your house number?" "Which bus goes to the high street?" 101 "A hundred and one." "One-oh-one." (Aquí, "oh" se usa para el dígito 0). "One-oh-one." 109 "A hundred and nine." "One-oh-nine." "One-oh-nine." 110 "A hundred and ten." "One-ten." "One-one-oh." 117 "A hundred and seventeen." "One-seventeen." "One-one-seven." 120 "A hundred and twenty." "One-twenty." "One-two-oh", "One-two-zero." 152 "A hundred and fifty-two." "One-fifty-two." "One-five-two." 208 "Two hundred and eight." "Two-oh-eight." "Two-oh-eight." 334 "Three hundred and thirtyfour." "Three-thirty-four." "Three-three-four." Tabla T.1.1.1.F Nota: Al escribir un cheque, el número 100 siempre se escribe como “one hundred”, no como “a hundred”. En inglés americano, a muchos estudiantes se les enseña a no usar la palabra “and” en cualquier parte del número, de forma que no es usada antes de las decenas y unidades. En su lugar se usa un delimitador verbal cuando se trata con números compuestos. Por lo tanto, en lugar de "three hundred and seventy-three", se diría "three hundred seventy-three". Para números superiores a un millón, hay dos formas distintas de nombrarlos: Escala grande (cada vez menos usada en inglés británico), donde mil millones se nombra con la palabra “milliard”, y un millón de millones con la palabra “billion”. Escala pequeña (usada en inglés americano y cada vez más en inglés británico), donde mil millones se nombra como “billion” y no se usa la palabra “milliard”. La siguiente tabla muestra estas diferencias:
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 8 de 72 Número Escala pequeña Escala grande 1,000,000 one million one million 1,000,000,000 one billion a thousand million one milliard a thousand million 1,000,000,000,000 one trillion a thousand billion one billion a million million 1,000,000,000,000,000 one quadrillion a thousand trillion one billiard a thousand billion 1,000,000,000,000,000,000 one quintillion a thousand quadrillion one trillion a million billion 1,000,000,000,000,000,000,000 one sextillion a thousand quintillion one trilliard a thousand trillion Tabla T.1.1.1.G Los números por encima de un trillón, en potencias ascendentes de diez, se componen de la siguiente forma: “quadrillion”, “quintillion”, “sextillion”, “septillion”, “octillion”, “nonillion”, “decillion”, “undecillion”, “duodecillion”, “tredecillion”, “quattuordecillion”, y “quindecillion”, que es un uno seguido de 48 ceros. El número más grande de esta lista es un mili-millón (“milli-millillion”), que es 10 elevado a 3 000 003. El término gúgol (“googol”) es el nombre de un número acuñado en 1938 por Milton Sirotta, un niño de 9 años, sobrino del matemático estadounidense Edward Kasner. Un gúgol es un uno seguido de cien ceros. Por su parte, un gúgolplex (“googolplex”) es un uno seguido de un gúgol de ceros, esto es, 10 elevado a la gugol-ésima potencia. Aunque el inglés británico ha utilizado tradicionalmente el sistema de escala grande, el uso de la escala pequeña se ha incrementado en los últimos años, hasta el punto de que el gobierno británico y los sitios web de la BBC usan exclusivamente la escala pequeña. La siguiente tabla muestra cómo se componen números largos en inglés americano:
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 9 de 72 Número Escrito Pronunciado 1,200,000 1.2 million one point two million 3,000,000 3 million three million 250,000,000 250 million two hundred fifty million 6,400,000,000 6.4 billion six point four billion 23,380,000,000 23.38 billion twenty-three point three eight billion Tabla T.1.1.1.H Con frecuencia, los números grandes se escriben con semiespacios para separar los miles (y, a veces, con espacios normales o apóstrofes) en lugar de comas, para evitar así confusiones en países donde se usa la coma decimal. Por lo tanto, un millón se escribe como 1 000 000. En algunas partes, se puede usar un punto como separador de miles, pero entonces el separador decimal debe ser una coma. 1.1.2. Números ordinales. Los números ordinales se refieren a una posición dentro de una serie. La forma de escribirlos es muy similar a los cardinales, aunque con algunas diferencias. Del 0 al 19 se escriben según la siguiente tabla: 0th zeroth 10th tenth 1st first 11th eleventh 2nd second 12th twelfth 3rd third 13th thirteenth 4th fourth 14th fourteenth 5th fifth 15th fifteenth 6th sixth 16th sixteenth 7th seventh 17th seventeenth 8th eighth 18th eighteenth 9th ninth 19th nineteenth Tabla T.1.1.2.A
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 16 de 72 Duodecillion 1039 1072 Tredecillion 1042 1078 Quattuordecillion 1045 1084 Quindecillion 1048 1090 Sexdecillion (Sedecillion) 1051 1096 Septendecillion 1054 10102 Octodecillion 1057 10108 Novemdecillion (Novendecillion) 1060 10114 Vigintillion 1063 10120 … … … … … … Centillion 10303 10600 Tabla T.1.1.6.A Aparte de “million”, las palabras de esta lista terminadas en “-illion” son derivadas de añadir prefijos (“bi-“, “tri-“, etc., derivadas del Latín) a la raíz. “Centillion” parece ser el nombre del número más alto terminado en “-illion” que está incluído en estos diccionarios. “Trigintillion”, frecuentemente citada en discusiones de nombres de números largos, no está incluida en ninguno de ellos, así como tampoco está ninguno de los nombres que pueden ser creados fácilmente extendiendo el patrón de nombres (“unvigintillion”, “duovigintillion”, “duoquinguagintillion”, etc.). Cada número por encima del millón tiene dos posibles nombres: uno para la escala corta, donde los sucesivos nombres difieren por un factor de un millar (103), y otro para la escala larga, donde los sucesivos nombres difieren por un factor de un millón (106). Una forma fácil de encontrar el valor de estos números en escala corta es tomar el número indicado por el prefijo (tal como 2 en “billion”, 4 en “quadrillion”, 18 en “octodecillion”, etc.), sumarle uno, y multiplicar el resultado por 3. Por ejemplo, en un “trillion”, el prefijo es “tri”, que significa 3. Sumándole 1 nos da 4. Ahora, multiplicando 4 por 3 nos da 12, que es la potencia a la cual se debe elevar 10 para expresar un “trillion” en escala corta en notación científica. Un “trillion” = 1012. En el caso de la escala larga, hay que multiplicar el número del prefijo por 6. Por ejemplo, para un “billion”, cuyo prefijo significa 2, multiplicando 2 por 6 nos da 12, que es la potencia a la cual se debe elevar 10 para expresar un “billion”
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 17 de 72 en escala larga en notación científica. Un “billion” = 1012. Los valores intermedios (“billiard”, “trilliard”, etc.) pueden ser convertidos del mismo modo, sumándole ½ al número del prefijo y multiplicándolo por 6. Por ejemplo, para “septilliard”, cuyo prefijo indica 7, sumándole ½ a 7 y multiplicándolo por 6 nos da 45. Un “septilliard” = 1045. El procedimiento de nombrar números largos está basado en tomar un número n en intervalos de 103n+3 (escala corta) o 106n (escala larga) y concatenar las raíces latinas para las posiciones de sus unidades, decenas y centenares, junto con el sufijo “-illion”. De esta forma, los números hasta 103·999+3 = 103000 (escala corta) o 106·999 = 105994 (escala larga) pueden ser nombrados. Unidades Decenas Centenares 1 Un N Deci NX Centi 2 Duo MS Viginti N Ducenti 3 Tre (*) NS Triginta NS Trecenti 4 Quattuor NS Quadraginta NS Quadringenti 5 Quinqua NS Quinquaginta NS Quingenti 6 Se (*) N Sexaginta N Sescenti 7 Septe (*) N Septuaginta N Septingenti 8 Octo MX Octoginta MX Octingenti 9 Nove (*) Nonaginta Nongenti Tabla T.1.1.6.B (*) ^ Cuando va precedido de un componente marcado como S o X, “tre” pasa a ser “tres” y “se” pasa a ser “ses” o “sex”; igualmente, cuando va precedido de un componente marcado como M o N, “septe” y “nove” pasan a ser “septem” y “novem” o “septen” y “noven”. Aplicando este procedimiento podemos completar la tabla vista anteriormente: Valor Escala Corta Escala Larga Valor Escala Corta Escala Larga … … … … … … 1066 Unvigintillion Undecillion 10111 Sestrigintillion Octodecilliard 1069 Duovigintillion Undecilliard 10114 Septentrigintillion Novendecillion 1072 Tresvigintillion Duodecillion 10117 Octotrigintillion Novendecilliard 1075 Quattuorvigintillion Duodecilliard 10120 Noventrigintillion Vigintillion 1078 Quinquavigintillion Tredecillion 10123 Quadragintillion Vigintilliard … … … … … … Tabla T.1.1.6.C
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 18 de 72 Todos los diccionarios incluyen “googol” (10100) y “googolplex” (1010 e 100), pero ninguno de ellos incluye nombres mayores de la familia del “googol”, como “googolduplex”, etc. El Oxford English Dictionary comenta que “googol” y “googolplex” no tienen un uso formal en matemáticas. 1.1.7. Números especiales. Algunos números tienen nombres especiales (adicionalmente a sus nombres regulares): 0: tiene otros nombres, dependiendo del contexto: o zero: formato científico o naught / nought: principalmente uso británico o aught: principalmente arcaico, pero aún utilizado ocasionalmente cuando un dígito en medio de un número es cero (como "thirtyaught-six", el cartucho del rifle .30-06 Springfield y cualquier asociación de armas que lo utilice) o oh: usado al deletrear números (por teléfono, cuentas bancarias, línea de autobús, etc.) o nil: en puntuaciones de determinados deportes que usan porterías, como fútbol, rugby, hockey, etc. (uso británico): ("The score is two–nil.") o nothing: en puntuaciones de deportes en general (uso americano): ("The score is two–nothing.") o null: usado técnicamente para referirse a un objeto o idea relativo con la nada. o love: en tenis, bádminton, squash y deportes similares. o zilch, nada (del español), zip: usado informalmente para enfatizar la nada; suele usarse especialmente en combinación de uno con otro: ("You know nothing—zero, zip, nada, zilch!") (uso americano) o nix: también usado como verbo (uso americano, principalmente) o cypher / cipher: arcaico, del francés “chiffre”
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 19 de 72 o goose egg: (informal) o duck: (usado en cricket) o blank: la mitad de una pieza de dominó sin puntos. 1: o ace: usado en ciertos deportes y juegos, como el tenis o el golf. o birdie: usado en golf. o solo: español. o unit: unidad. o linear: el grado de un polinomio si es 1. o unity: en matemáticas. 2: o couple: pareja. o pair: par. o deuce: la cara de un dado, carta o dominó con dos puntos. o “eagle” en golf denota dos golpes menos que un “par”. o duo: dúo. o quadratic: el grado de un polinomio si es 2. 3: o trey: la cara de un dado o carta con 3 puntos, canasta de 3 puntos en baloncesto. o trio: trío. o trips: trío en una mano de póker (3 cartas con el mismo número). o cubic: el grado de un polinomio si es 3. o albatross: usado en golf.
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 20 de 72 4: o cater: la cara de un dado o carta con cuatro puntos. o quartet: cuarteto. o “quartic” o “biquadratic”: el grado de un polinomio si es 4. o quad: abreviatura de “quadruple”. o condor: usado en golf. 5: o cinque: la cara de un dado o carta con 5 puntos. o quintet: quinteto. o nickel: en americano informal, 5 centavos, pero aplicado a referencias no monetarias. o quintic: el grado de un polinomio si es 5. o quint: abreviatura de “quintuplet”. 6: o half a dozen: media docena. o sice: la cara de un dado o carta con 6 puntos. o sextet: sexteto. o “sextic” o “hectic”: el grado de un polinomio si es 6. 7: o septet: septeto. o “septic” or “heptic”: el grado de un polinomio si es 7. 8: octet: octeto. 9: nonet: noneto.
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 21 de 72 10: o a metric dozen: una docena métrica. o dime: en americano informal, el valor de 10 centavos, pero aplicado a referencias no monetarias. o decet: deceto. 11: a banker's dozen. 12: a dozen (primera potencia de la base), usado principalmente en comercio. 13: a baker's dozen. Una docena + 1. 20: a score (primera potencia de la base vigesimal), actualmente arcaico. 50: half a century. Medio siglo, también usado en resultados de Cricket. 100: o a century: un siglo, también usado en resultados de Cricket. o a ton, en inglés de la “Commonwealth”, la velocidad de 100 mph o 100 km/h. 120: a great hundred: doce decenas, o también “small gross” (diez docenas), ambos arcaicos. A veces también puede ser referido como “duodecimal hundred”. 144: a gross. Una docena de docenas (segunda potencia de la base duodecimal), usado principalmente en comercio. 1000: o a grand, coloquialmente usado en especial cuando se refiere a dinero, también en fracciones y múltiplos, por ejemplo “half a grand”, “two grand”, etc. o K, originalmente de la abreviación de kilo-, por ejemplo "He only makes $20K a year." 1728: a great gross (a dozen gross, tercera potencia de la base duodecimal), usado principalmente en comercio.
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 22 de 72 10,000: a myriad (a hundred hundred), comúnmente usado en el sentido de un número indefinido muy alto. 100,000: a lakh (a hundred thousand), procedente del inglés indio. 10,000,000: a crore (a hundred lakh), procedente del inglés indio. 10100: googol (1 seguido de 100 ceros), usado en matemáticas. 10googol: googolplex (1 seguido de un googol de ceros) 10googolplex: googolplexplex (1 seguido de un googolplex de ceros) Las combinaciones de números en la mayoría de las puntuaciones deportivas son leídas como en los siguientes ejemplos: 1–0 Inglés británico: one-nil; Inglés americano: “one-nothing”, “onezip”, o “one-zero”. 0–0 Inglés británico: “nil-nil”, o rara vez “nil all”; Inglés americano: “zero-zero” o “nothing-nothing”, (ocasionalmente “scoreless” o “no score”) 2–2 “two-two” o “two all”; Inglés americano: también “twos”, “two to two”, “even at two”, o “two up”. En el caso de las puntuaciones de Tenis, las convenciones de nombres son distintas al resto de deportes. 1.2. Normas para decidir si escribimos dígitos o palabras. Escribir números con palabras es una práctica que puede parecernos incómoda e innecesaria, pero lo cierto es que en determinadas circunstancias se convierte en algo recomendable, si no necesario. ¿Y cuáles son esas circunstancias? – En el caso que nos ocupa, que es en el idioma inglés, se ha estipulado una serie de normas para decidir, sistemáticamente, si escribimos un número mediante dígitos o mediante palabras. Algunas de estas normas son las siguientes: Escribir con palabras los números que puedan escribirse con una o dos palabras, números redondos y números ordinales. En escritura académica general, se debe escribir estos números con palabras:
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 23 de 72 todos los que estén por debajo de cien (por ejemplo “ninety-nine”), los números redondos (por ejemplo “four hundred”, “two thousand”, etc.), y los números ordinales (por ejemplo “third”, “twenty-fifth”, etc.). Escribir con palabras los números que comienzan una frase. Si esto resulta muy incómodo, es preferible reconstruir la frase para evitar empezar con el número. En el caso de fechas sí está permitido. Escribir con palabras números aproximados y algunas horas del día. En escritura académica no técnica, se puede escribir con palabras números aproximados a una cifra real, incluyendo fracciones (por ejemplo “about half the students”, “hundreds of times”, etc), así como medias horas y cuartos de hora (por ejemplo “six o’clock”, “quarter past seven”, “midday”, “half past six”, etc.). Evitar confusiones entre números dentro de una frase. Cuando se usan dos números juntos o se reparten dentro de una frase, es necesario utilizar palabras en alguno de ellos (por ejemplo “The computer laboratory hast 24 thirty-centimetre monitors”). Escribir con palabras números ordinales en nombres, y también en nombres numéricos de calles (por ejemplo “The Third Reich”, “The Fourth Estate”, “Sixth Avenue”, etc). Escribir con palabras en documentos legales u oficiales, donde la claridad es esencial (por ejemplo “the sum of nine hundred and forty-three pounds sterling”, “a distance of no less than two hundred yards from the plaintiff”, etc). Escribir dígitos en lugar de palabras para números mayores que cien y en las siguientes situaciones: o Dinero: Usar dígitos para cantidades exactas (por ej. 24.28€), pero usar dígitos y palabras para cantidades redondas y grandes (por ej. 15 million). o Edad: Usar dígitos para especificar la edad de una persona (por ej. 58 years old).
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 24 de 72 o Medidas: Usar dígitos con el símbolo de medida (por ej. 6 cm). o Porcentajes: Usar “55%”, “55 percent” o “fifty-five percent”. o Fracciones y decimales: En el caso de las fracciones, se puede escribir con dígitos o palabras. Si se usan palabras, se debe unir la parte fraccional con un guión (por ej. 2/3 o “twothirds”). En el caso de los decimales, dar las cantidades exactas en dígitos (por ej. 0.45). o Encuestas: Escribir los resultados de la encuesta con dígitos. o Puntuaciones de juegos y deportes: Escribir las puntuaciones con dígitos. o Estadísticas: Usar dígitos para describir información estadística. o Direcciones: Usar dígitos para indicar una dirección (por ej. “47 Marston Street”). o Nombres de carreteras: Usar dígitos para indicar una carretera (por ej. “A40”, “M25”, etc). o Épocas: Elegir dentro de una variedad de formatos, pero ser consistente (por ej. “the eighteen century” o “the 18th century”, “from the 1960s to the 1990s”). o Fechas: Usar este orden (día/mes/año) consistentemente (por ej. “Tuesday 23 February 2008”). o Horas del día: Elegir dentro de una variedad de formatos, pero ser consistente (por ej. “9 am” o “9.00 am” o “8.22 pm”). Si no se está usando “am” o “pm”, escribir la hora con palabras (por ej. “the eight-thirty bus”, “four o’clock in the afternoon”). Para mediodía y media noche, escribir con palabras (“midday” o “midnight” respectivamente). o Períodos: Usar dígitos (por ej. “pages: 56-74”, “115-117”, “streets 36-99 Spa St”).
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 25 de 72 o Secciones de un libro: Usar dígitos para referirnos a las secciones de libros (por ej. “volume 5”, “chapter 6”, “page 45”, etc). 1.3. Objetivos a cubrir en este trabajo. Como hemos visto, si queremos manejar correctamente el idioma, es necesario saber escribir números con palabras. Obviamente, escribir números pequeños parece bastante fácil, pero… ¿y si tuviéramos que escribir números más grandes? –No es, ni muchísimo menos, algo habitual, sobre todo teniendo en cuenta la norma que hemos comentado de escribir con dígitos los números mayores que cien, pero simplemente por una cuestión de curiosidad, o bien por ampliar nuestros conocimientos sobre el idioma, merece la pena disponer de una herramienta que realice estas complejas combinaciones de palabras por nosotros. Por otra parte, tal como vimos en el apartado anterior sobre conceptos generales, un número puede escribirse de varias formas: en escala corta, escala grande, utilizando comas o palabras “and” como separadores, etc. Normalmente cada persona está acostumbrada a escribir números siempre de la misma manera, pero conocer otras formas alternativas puede resultar útil e interesante, como por ejemplo el uso de la palabra “oh” por parte de los americanos para referirse a un cero. Con todo ello, la publicación de este servicio web pretende cubrir los siguientes objetivos: Dar a conocer las distintas alternativas a la hora de escribir un número con palabras. Enseñar cómo concatenar correctamente las palabras que componen un número, independientemente de su tamaño. Aportar una herramienta de comprobación ortográfica en la escritura de números. Servir de apoyo a otras aplicaciones informáticas.
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 32 de 72 Para enlazar cualquier aplicación con este servicio, es necesario conocer el formato de la entrada y de las salidas que genera. A continuación pasamos a describirlas. 5.1.1. Entrada. Como se detallará más adelante, la clase Conversor contiene un método llamado Convertir, que es el encargado de realizar todo el proceso, y que requiere un parámetro de entrada de tipo texto, que es el número que se desea convertir, escrito con dígitos numéricos. El número máximo de dígitos admitidos varía dependiendo del formato del número. Si el número está expresado en notación científica, se considerará tanto la longitud de su base y exponente, como su longitud una vez convertido a notación decimal. También se admiten números negativos, números fraccionarios, e incluso números romanos, en cuyo caso se realiza una conversión a número entero y se trata como tal. El número introducido debe cumplir con al menos uno de los siguientes formatos, dentro de los cuales se debe seguir estrictamente el orden indicado de sus partes: Número entero Parte 1: [OPCIONAL]: un signo + o un signo - (y sólo uno). Parte 2: [OBLIGATORIA]: de 1 a 603 dígitos numéricos. Número decimal Parte 1: [OPCIONAL]: un signo + o un signo - (y sólo uno). Parte 2: [OBLIGATORIA]: de 1 a 603 dígitos numéricos. Parte 3: [OBLIGATORIA]: un punto (separador decimal) seguido de 1 a 306 dígitos numéricos. Número fraccionario Parte 1: [OPCIONAL]: un signo + o un signo - (y sólo uno). Parte 2: [OBLIGATORIA]: de 1 a 603 dígitos numéricos.
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 33 de 72 Parte 3: [OBLIGATORIA]: un signo / para separar el Numerador del Denominador. Parte 4: [OPCIONAL]: un signo + o un signo - (y sólo uno). Parte 5: [OBLIGATORIA]: de 1 a 603 dígitos numéricos. Número en notación científica Parte 1: [OPCIONAL]: un signo + o un signo - (y sólo uno). Parte 2: [OBLIGATORIA]: De 1 a 603 dígitos numéricos. Parte 3: [OPCIONAL]: un punto (separador decimal) seguido de 1 a 306 dígitos numéricos. Parte 4: [OBLIGATORIA]: una letra "e" o una "E" (y sólo una). Parte 5: [OPCIONAL]: un signo + o un signo - (y sólo uno). Parte 6: [OBLIGATORIA]: de 1 a 3 dígitos numéricos. Número romano Formato habitual de los números romanos. Se permite que las letras estén escritas en minúscula. 5.1.2. Salidas. Como hemos comentado, el método Convertir realiza todo el proceso de conversión. Dicho proceso se descompone en varias tareas de conversión que se ejecutan simultáneamente, confluyendo todas en una integración de resultados que da lugar al conjunto de resultados definitivos, y que constituye el valor devuelto por el método. El tipo de datos devuelto se corresponde con la subclase pública Res_Def, que será descrita más adelante. Si por algún motivo surgieran errores en el proceso, las descripciones de los mismos pueden obtenerse mediante la propiedad Errores, de tipo ArrayList, dentro de dicha subclase.
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 34 de 72 Por lo tanto, la aplicación que vaya a publicar los resultados debería comprobar previamente si se ha generado algún error. 5.1.3. Tipos de resultados. Los tipos de resultados obtenidos dependen de la longitud y formato del número a convertir. El límite del servicio está fijado en los 1 000 centillones menos uno, tanto en escala corta como en escala larga. Esto provoca una asimetría entre ambos tipos de resultados, ya que en escala corta sólo podemos llegar hasta los 306 dígitos (10306), mientras que en escala larga podemos llegar nada más y nada menos que hasta los 603 dígitos (10603). La siguiente figura representa gráficamente la relación entre el número de dígitos y los resultados que se pueden obtener: Figura F.5.1.3.A A continuación veremos de una forma más detallada los distintos tipos de resultados que se pueden dar según el formato del número:
Trabajo de Fin de Grado: Conversión de Números a Texto en Inglés Página 35 de 72 Formato del número Longitud (núm. de dígitos) Tipo de resultado Especial (*) General (**) Por pares de dígitos (***) Escala corta Escala larga Cardinal / Decimal Ordinal Cardinal Cardinal / Decimal Ordinal Cardinal / Decimal Ordinal Entero Entre 1 y 3 SÍ SÍ SÍ NO NO NO NO NO 4 SÍ SÍ SÍ SÍ NO NO NO NO Entre 5 y 9 SÍ SÍ SÍ NO NO NO NO NO Entre 10 y 306 NO NO NO NO SÍ SÍ SÍ SÍ Entre 307 y 603 NO NO NO NO NO NO SÍ SÍ Decimal P. Entera: Entre 1 y 3 P. Decimal: Entre 1 y 306 NO SÍ NO NO NO NO NO NO P. Entera: Entre 4 y 9 P. Decimal: Entre 1 y 306 NO SÍ NO NO NO NO NO NO P. Entera: Entre 10 y 306 P. Decimal: Entre 1 y 306 NO NO NO NO SÍ NO SÍ NO P. Entera: Entre 307 y 603 P. Decimal: Entre 1 y 306 NO NO NO NO NO NO SÍ NO Fraccionario Numerador: Entre 1 y 603 Denominador: Entre 1 y 603 Se tratan el Numerador y Denominador con formato de Entero y se combinan los resultados de Cardinal del Numerador con los de Ordinal del Denominador. Quedan excluidos los resultados de tipo “Especial” y “Por pares de dígitos”. Si se puede obtener el resultado de la división entre el Numerador y el Denominador, éste se trata con formato Decimal y se añaden sus resultados a los del Número Fraccionario. Notación científica Se convierte el número a Notación decimal y se trata como tal. Romano Se convierte el número a Entero y se trata como tal. Tabla T.5.1.3.A (*) Resultado especial: A determinados números se les asigna un nombre relacionado con el contexto en el que se utilizan, por ejemplo, en deportes. (**) Resultado general: Consideramos un resultado como “general” cuando el resultado en Escala Corta es el mismo que en Escala Larga. (***) Por pares de dígitos: En inglés americano, los números de 4 dígitos suelen nombrarse por pares de dígitos en determinados contextos. Por ejemplo: 1974 “Nineteen seventy-four”
Trabajo de Fin de Grado: Conversión de Números a Texto en Inglés Página 36 de 72 5.2. Vista general del proceso de conversión. Antes de describir la estructura de la clase Conversor, conviene comprender cómo se ha planteado el mecanismo de conversión. Existen varios “caminos” alternativos hasta la obtención de resultados, dependiendo del formato del número introducido. La siguiente figura ilustra el diagrama de flujo de la conversión:
Trabajo de Fin de Grado: Conversión de Números a Texto en Inglés Página 37 de 72 Figura F.5.2.A
Trabajo de Fin de Grado: Conversión de Números a Texto en Inglés Página 38 de 72 El proceso puede describirse brevemente en los siguientes pasos: 1. Desde una aplicación externa se crea una instancia de la clase Conversor. 2. Se llama al método Convertir de dicha clase, pasándole como parámetro el número a convertir. A partir de ese momento, el método Convertir realiza las siguientes tareas: 3. Se valida el formato del número. Si el formato no es correcto, se genera un error y se finaliza el proceso. En caso contrario, se analiza el número de la siguiente forma: Si no es un formato numérico: se comprueba si se trata de un número romano, en cuyo caso se convierte a entero. Si no, se genera un error y finaliza el proceso. Si se detecta un signo de división (considerado como indicador de que es un número fraccionario) se descompone en numerador y denominador. Si la longitud de ambos permite obtener el resultado de la división, se procede a validar el formato de dicho resultado, siguiendo estos mismos pasos. Si se detecta un punto (considerado como separador decimal), se descompone en parte entera y parte decimal. También se admiten números negativos y notación científica. En este último caso, se realiza una conversión a notación decimal. Si un número no fraccionario no tiene parte decimal, se considera como parte entera el número completo. 4. Con cada una de las partes devueltas por la validación (parte entera y parte decimal cuando el número no es fraccionario, o bien numerador y denominador cuando sí lo es), se realizan simultáneamente tareas de conversión a texto en distintos formatos, según proceda: números especiales, escala corta, escala larga, decimal, etc. Estas conversiones pueden, a su vez, generar diversos tipos de resultados, como texto cardinal, texto ordinal, números romanos, etc. En la mayor parte de los casos se amplía el conjunto de resultados obtenidos, por ejemplo sustituyendo comas por palabras “and”, que es la forma utilizada
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 39 de 72 habitualmente en inglés británico, o bien sustituyendo “one” por “a” al comienzo del texto, si se trata de un número que empieza por un dígito de unidad o centena igual a uno. 5. Tras esperar a que finalicen todas las conversiones, se envían los resultados obtenidos a un proceso de Integración de Resultados, que se encarga de combinar unos con otros de forma coherente y devolverlos agrupados por categorías, que indican qué tipo de resultados contienen. De nuevo, desde la aplicación externa: 6. Se comprueba si ha habido algún error en la conversión. Si no lo hay, se obtienen los resultados agrupados por categorías que fueron devueltos por el proceso de integración. 5.3. Estructura de la clase Conversor. Tal como hemos adelantado, el servicio consta únicamente de una clase llamada Conversor, que encapsula todos los componentes necesarios para el proceso de conversión. En la siguiente figura podemos ver un diagrama general de su estructura:
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 40 de 72 Figura F.5.3.A Como se puede apreciar, contiene dos subclases: Res_Par, que es privada y se encarga del almacenamiento de resultados parciales, y Res_Def, que es pública y se encarga del almacenamiento de los resultados definitivos. Por otra parte, contiene dos métodos: el constructor, que no requiere parámetros, y el método Convertir, que es el encargado de inicializar y lanzar el proceso de conversión. Este método devuelve una instancia de la clase Res_Def con los resultados definitivos de la conversión.
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 41 de 72 Aunque no se muestran en la figura, por tratarse de una descripción a nivel general, la clase Conversor también consta de definiciones de tipos, variables globales, constantes y funciones locales. A continuación se detallan todos los componentes. 5.3.1. Clase Res_Par. Esta subclase es la encargada de almacenar los resultados parciales que generan las distintas tareas de conversión. Es de ámbito privado, y por tanto sólo es accesible desde dentro de la clase Conversor. Figura F.5.3.1.A El tipo enumerado e_Lado indica el lado por el que se produce la concatenación en la cadena de un resultado (izquierda, derecha o sobreescribir).
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 48 de 72 Figura F.5.3.2.D
Trabajo de Fin de Grado: Conversión de Números a Texto en Inglés Página 49 de 72 5.3.3. Definiciones de tipos. La clase Conversor contiene las siguientes declaraciones de tipos de datos: Figura F.5.3.3.A El tipo enumerado e_Conv indica el tipo de conversión a realizar, siendo sus posibles valores Cardinal, Ordinal o Ambas. Dependiendo de las características del número a convertir se ejecutan unos tipos de conversión u otros. El tipo enumerado e_Idioma indica el idioma de las descripciones, tanto de los resultados como de los errores. El tipo estructurado t_Numero se utiliza para guardar las distintas partes que pueden componer un número. Sus campos son PEntera (Parte Entera) y PDecimal (Parte Decimal), que se utilizan para números enteros y decimales, y Numerador y Denominador, que se utilizan para números fraccionarios. 5.3.4. Variables globales. La clase Conversor contiene las siguientes variables globales:
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 50 de 72 Figura F.5.3.4.A Los arrays v_ValorNumRom, v_ValorNumRom_2, v_NumRom y la variable v_NumRom_2 se utilizan para la conversión de números romanos a números enteros y viceversa. Los arrays v_Pref_1, v_Pref_2, v_Pref_3 y v_Pref_4 se utilizan como prefijos en la construcción dinámica del array de Textos de Grupos de Dígitos, que se explicará detalladamente en la sección de Desarrollo. 5.3.5. Funciones locales. A continuación se detallan las funciones locales de la clase: Nombre Validar_Formato Descripción Comprueba si el texto original tiene un formato correcto, y, en caso afirmativo, separa el número en parte entera y parte decimal, o bien en numerador y denominador. Argumentos de Entrada ae_Numero (String): Texto original del número (dígitos) ae_Idioma (e_Idioma): Idioma de las descripciones de error. Argumentos de Salida as_Numero (t_Numero): Número separado en sus correspondientes partes. as_Negativo (Boolean): Indica si el número es negativo. as_Errores (ArrayList): Lista de errores. Valor devuelto (Boolean): Verdadero si el formato es correcto, y falso en caso contrario. Tabla T.5.3.5.A
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 51 de 72 Nombre Convertir_Notacion_Decimal Descripción Convierte un número de Notación Científica a Notación Decimal. Argumentos de Entrada ae_Numero (String): Número a convertir. Argumentos de Salida as_Errores (ArrayList): Lista de errores. Valor devuelto (String): Número en Notación Decimal. Tabla T.5.3.5.B Nombre Concatenar_And Descripción Concatena la palabra “and” en un texto de número. Argumentos de Entrada ae_Texto_Numero (String): Texto de Número. ae_Texto_Grupos (String[] – Opcional): Textos de Grupos de Dígitos. Argumentos de Salida as_Errores (ArrayList): Lista de errores. Valor devuelto (String): Texto de Número con palabras “and” concatenadas. Tabla T.5.3.5.C Nombre Eliminar_Ceros_NS Descripción Elimina los ceros no significativos de un número: si es una parte entera los que estén por la izquierda; si es una parte decimal, los que estén por la derecha. Además, si el número comienza por un signo + o un -, elimina dicho signo. Argumentos de Entrada ae_Numero (String): Número. ae_Decimal (Boolean): Indica si se trata de una parte decimal. Argumentos de Salida as_Errores (ArrayList): Lista de errores. Valor devuelto (String): Número sin signo ni ceros no significativos. Tabla T.5.3.5.D Nombre Obtener_Grupo_Cardinal Descripción Obtiene la conversión a cardinal de un grupo de 3 dígitos (o menos). Argumentos de Entrada ae_Digitos_Grupo (String): Dígitos del Grupo. Argumentos de Salida as_Resultado (String): Resultado de la Conversión. as_Errores (ArrayList): Lista de errores. Valor devuelto (Boolean): Verdadero si la conversión tiene éxito, y falso en caso contrario. Tabla T.5.3.5.E
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 52 de 72 Nombre Obtener_Grupo_Ordinal Descripción Obtiene la conversión a ordinal de un grupo de 3 dígitos (o menos). Argumentos de Entrada ae_Digitos_Grupo (String): Dígitos del Grupo. Argumentos de Salida as_Resultado (String): Resultado de la Conversión. as_Errores (ArrayList): Lista de errores. Valor devuelto (Boolean): Verdadero si la conversión tiene éxito, y falso en caso contrario. Tabla T.5.3.5.F Nombre Cargar_Textos_Grupos Descripción Carga los textos de grupos en un array. Argumentos de Entrada ae_NumGrupos (int): Número de Grupos. Argumentos de Salida as_Textos_Grupos (String[]): Array con los Textos de los Grupos. as_Errores (ArrayList): Lista de errores. Valor devuelto Ninguno. Tabla T.5.3.5.G Nombre Gen_Result_Especial Descripción Genera los resultados de la conversión de la parte entera a números especiales. Argumentos de Entrada ae_ PEntera (String): Parte entera del número. ae_Idioma (e_Idioma): Idioma de las descripciones. Argumentos de Salida Ninguno. Valor devuelto (Res_Par): Resultados de la conversión. Tabla T.5.3.5.H Nombre Gen_Result_Par_Dig Descripción Genera los resultados de la conversión de la parte entera a pares de dígitos. Argumentos de Entrada ae_ PEntera (String): Parte entera del número. ae_Idioma (e_Idioma): Idioma de las descripciones. Argumentos de Salida Ninguno. Valor devuelto (Res_Par): Resultados de la conversión. Tabla T.5.3.5.I
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 53 de 72 Nombre Gen_Result_General Descripción Genera los resultados de la conversión de la parte entera a texto general. Argumentos de Entrada ae_ PEntera (String): Parte entera del número. ae_Tipo_Result (e_Conv): Tipos de resultados a obtener. ae_Negativo (Boolean): Indica si el número es negativo. Argumentos de Salida Ninguno. Valor devuelto (Res_Par): Resultados de la conversión. Tabla T.5.3.5.J Nombre Gen_Result_ECorta Descripción Genera los resultados de la conversión de la parte entera a escala corta. Argumentos de Entrada ae_ PEntera (String): Parte entera del número. ae_Tipo_Result (e_Conv): Tipos de resultados a obtener. ae_Negativo (Boolean): Indica si el número es negativo. ae_Idioma (e_Idioma): Idioma de las descripciones. Argumentos de Salida Ninguno. Valor devuelto (Res_Par): Resultados de la conversión. Tabla T.5.3.5.K Nombre Gen_Result_ELarga Descripción Genera los resultados de la conversión de la parte entera a escala larga. Argumentos de Entrada ae_PEntera (String): Parte entera del número. ae_Tipo_Result (e_Conv): Tipos de resultados a obtener. ae_Negativo (Boolean): Indica si el número es negativo. ae_Idioma (e_Idioma): Idioma de las descripciones. Argumentos de Salida Ninguno. Valor devuelto (Res_Par): Resultados de la conversión. Tabla T.5.3.5.L Nombre Gen_Result_Decimal Descripción Genera los resultados de la conversión de la parte decimal. Argumentos de Entrada ae_PDecimal (String): Parte decimal del número. ae_Idioma (e_Idioma): Idioma de las descripciones. Argumentos de Salida Ninguno. Valor devuelto (Res_Par): Resultados de la conversión. Tabla T.5.3.5.M
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 54 de 72 Nombre Integrar_Resultados Descripción Integra y combina los resultados parciales obtenidos y los devuelve en un único conjunto. Argumentos de Entrada ae_Idioma (e_Idioma): Idioma de las descripciones. ae_Negativo (Boolean): Indica si el número es negativo. ae_Result_PEntera_Num (List<Res_Par>): Resultados de la parte entera o numerador si el número es fraccionario. ae_Result_PDecimal (Res_Par - Opcional): Resultados de la parte decimal. ae_Result_Den (List<Res_Par> - Opcional): Resultados del denominador (números fraccionarios). ae_Numerador (String – Opcional): Numerador (números fraccionarios). ae_Denominador (String – Opcional): Denominador (números fraccionarios). ae_Romanos (String – Opcional): Números romanos. Argumentos de Salida Ninguno. Valor devuelto (Res_Def): Conjunto de Resultados Definitivos. Tabla T.5.3.5.N Nombre Conv_Entero_Romano Descripción Convierte un número entero a romano. Argumentos de Entrada ae_PEntera (String): Parte entera del número. Argumentos de Salida as_Errores (ArrayList): Lista de errores. Valor devuelto (String): Número escrito en romano. Tabla T.5.3.5.O Nombre Conv_Romano_Entero Descripción Convierte un número romano a entero. Argumentos de Entrada/Salida as_NumRomano (String): Número escrito en romano. as_Errores (ArrayList): Lista de errores. Valor devuelto (int): Valor del número. Tabla T.5.3.5.P Nombre Formatear_Parte_Numero Descripción Formatea una parte de un número, separando cada grupo de tres dígitos con un espacio. Argumentos de Entrada ae_Parte (String): Parte del número. Valor devuelto (String): Número formateado. Tabla T.5.3.5.Q
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 55 de 72 Nombre Obtener_Digitos_Decimales Descripción Obtiene la conversión a texto de un conjunto de dígitos decimales (formato BrE con “point”). Argumentos de Entrada ae_Digitos (String): Dígitos decimales. Argumentos de Salida as_Resultado (String): Resultado de la conversión. as_Errores (ArrayList): Lista de errores. Valor devuelto (Boolean): Verdadero si la conversión es correcta. Tabla T.5.3.5.R Nombre Logs Descripción Escribe en un fichero las consultas realizadas al servicio. Argumentos de Entrada ae_Numero (String): Número consultado. ae_Error (int): Código de error. Valor devuelto Ninguno. Tabla T.5.3.5.S 5.3.6. Métodos. Nombre Conversor (Constructor) Descripción Constructor implícito de la clase (no implementado en el código). Argumentos de Entrada Ninguno. Argumentos de Salida Ninguno. Valor devuelto Instancia de la clase Conversor. Tabla T.5.3.6.A Nombre Convertir Descripción Crea una instancia de la clase e inicializa variables. Argumentos de Entrada ae_Numero (String): Número a convertir en texto. ae_Idioma (e_Idioma): Idioma de las descripciones. Argumentos de Salida as_Numero_Formateado (String): Número formateado. as_NumCategorias (int): Número de categorías de los resultados obtenidos. as_NumResultados (int): Número total de resultados obtenidos. Valor devuelto (Res_Def): Conjunto de Resultados Definitivos. Tabla T.5.3.6.B
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 56 de 72 6. DESARROLLO. Para la implementación del servicio se ha empleado el lenguaje C#. El código desarrollado contempla las siguientes características: Programación orientada a objetos: implementación de clases. Expresiones regulares: uso de patrones de caracteres para la validación del formato del número introducido por el usuario. Concurrencia: ejecución de múltiples tareas de conversión simultáneamente, con lo que se obtiene mayor velocidad en la obtención de resultados. Fraccionamiento y concatenación: fraccionamiento del número que se desea convertir en grupos de tres dígitos para obtener resultados por partes y concatenación de dichas partes. Construcción dinámica de términos con prefijos y sufijos: construcción, en tiempo de ejecución, de los términos asociados a los grupos de tres dígitos usando una serie de prefijos y sufijos. Integración de resultados: combinación e integración de los resultados parciales para obtener los resultados definitivos. Mejora de rendimiento a través de la clase StringBuilder: uso de objetos de esta clase, en lugar de objetos tipo String, en aquellos casos donde hay repetidas modificaciones de cadenas de texto. Veamos ahora con detalle de qué forma se han empleado dichas características. 6.1. Programación orientada a objetos. Tras explicar el diseño de la clase Conversor, queda claro que se trata de una programación orientada a objetos, donde encontramos métodos y propiedades entre otros componentes. Además encontramos un anidamiento de clases, ya que la clase Conversor contiene otras dos subclases: Res_Par y Res_Def.
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 57 de 72 6.2. Expresiones regulares. Antes de iniciar las tareas de conversión sobre un número, es indispensable verificar que el formato de dicho número es correcto. Una forma de hacerlo, sin tener que desarrollar demasiado código, es usando expresiones regulares. Una expresión regular es una secuencia de caracteres que forma un patrón de búsqueda, principalmente utilizada para la búsqueda de patrones de cadenas de caracteres u operaciones de sustituciones. La secuencia puede estar formada por uno o más literales de carácter, operadores o estructuras. La lista de caracteres que se pueden utilizar para definir una expresión regular es bastante extensa, por lo que no procede detallarla por completo en este documento. Sin embargo, sí que podemos desglosar y explicar las expresiones regulares utilizadas para verificar el formato del número introducido por el usuario. La función Validar_Formato, de la clase Conversor, utiliza tres patrones distintos para esta verificación; uno para números no fraccionarios, otro para números fraccionarios, y otro para números romanos. A continuación pasamos a detallarlos: Números no fraccionarios: (\+?|\-?)\d{1,603}(\.\d{1,306})?((e|E)(\+?|\-?)\d{1,3})? Caracteres Opcional Descripción (\+?|\-?) Sí Un signo + o un signo – (y sólo uno). \d{1,603} No De 1 a 603 dígitos numéricos. (\.\d{1,306})? Sí Un punto (separador decimal) seguido de 1 a 306 dígitos numéricos. ((e|E)(\+?|\-?)\d{1,3})? Sí Una letra "e" o una "E" (y sólo una), seguida OPCIONALMENTE por un signo + o un signo - (y sólo uno), seguido de 1 a 3 dígitos numéricos para expresar Notación Científica. Tabla T.6.2.A Números fraccionarios: (\+?|\-?)\d{1,603}\/(\+?|\-?)\d{1,603}
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 64 de 72 million, two hundred fifty-five thousand, four hundred five five hundred thirty thousand million, seven hundred sixty-five million, two hundred fifty-five thousand, four hundred five Tabla T.6.4.A Ejemplo: con la categoría Ordinal – Escala Larga – BrE: Iteración Grupo Resultados 1 405 four hundred fifth 2 255 two hundred fifty-five thousand, four hundred fifth 3 765 seven hundred sixty-five million, two hundred fifty-five thousand, four hundred fifth 4 530 five hundred thirty milliard, seven hundred sixty-five million, two hundred fifty-five thousand, four hundred fifth five hundred thirty thousand million, seven hundred sixty-five million, two hundred fifty-five thousand, four hundred fifth Tabla T.6.4.B Nota: Aunque se trata de inglés británico, la concatenación con “and” no se hace desde el primer momento, sino en la ampliación de resultados. Paso 4: Se amplían los resultados. Hasta este momento las categorías de resultados son: o Cardinal – Escala Corta – AmE o Ordinal – Escala Corta – AmE o Cardinal – Escala Larga – BrE (sin concatenar aún con “and”) o Ordinal – Escala Larga – BrE (sin concatenar aún con “and”) Concatenando sus resultados con “and” (Por ej: “five hundred and thirty…”) se obtienen estas dos nuevas categorías: o Cardinal – Escala Corta – BrE o Ordinal – Escala Corta – BrE Y se corrigen: o Cardinal – Escala Larga – BrE o Ordinal – Escala Larga – BrE
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 65 de 72 En total, 6 categorías con 2 resultados cada una, por lo que tenemos un total de 12 resultados. Si el primer o tercer dígito del grupo más significativo hubiese sido 1, se añadirían nuevos resultados sustituyendo el primer “one…” por “a…”. Por ejemplo, para el número 130,765,255,405: “one hundred and thirty…” “a hundred and thirty…” El conjunto de resultados definitivo es el mostrado en el apartado sobre la clase Res_Def. 6.5. Construcción dinámica de términos con prefijos y sufijos. Cada grupo de tres dígitos, salvo el menos significativo, lleva asociado un término que define su peso o ponderación dentro del número. Así, el segundo grupo se corresponde con el término “thousand” (mil), el tercero con “million” (millón), el cuarto con “billion” (billón), y así sucesivamente. Para proporcionar la mayor flexibilidad posible al código y no tener que insertar mediante texto fijo todos estos términos, que son muchos, teniendo en cuenta el número máximo de dígitos permitido, se ha implementado una función que construye y devuelve, en tiempo de ejecución, un array con los términos necesarios para definir el número. Únicamente se precisa la siguiente inicialización de cuatro arrays de Prefijos: v_Pref_1 = {"m", "b", "tr", "quadr", "quint", "sext", "sept", "oct", "non"}; v_Pref_2 = {"dec", "vi", "tri", "quadra", "quinqua", "sexa", "septua", "octo", "nona"}; v_Pref_3 = {"un", "duo", "tre", "quattuor", "quin", "sex", "septen", "octo", "noven"}; v_Pref_4= {"un", "duo", "tres", "quattuor", "quinqua", "sex", "septen", "octo", "noven"}; Esta función se llama Cargar_Textos_Grupos, y se utiliza tanto para generar texto en cardinal como en ordinal, e incluso para la parte decimal, añadiendo en este último caso el sufijo “th” o “ths” a cada término. El límite está en el término “centillion” (303 dígitos en Escala Corta). A continuación describimos el algoritmo que sigue dicha función:
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 66 de 72 Se definen las siguientes constantes: o K_Suf_1 = “illion” o K_Suf_2 = “gintillion” o K_Ths = “ thousand“ o K_Cent = “centillion” Se redimensiona el array con el número de grupos que componen el número (número de dígitos / 3). Cada elemento del array contendrá el término asociado a un grupo de tres dígitos. Se inicializa sólo el primer elemento del array con la constante K_Ths (“thousand”), ya que la raíz de este término es distinta al resto. El resto de términos se construye concatenando los prefijos y sufijos definidos anteriormente de la siguiente manera: o Si es un grupo entre los dígitos 6 y 30 (desde “Million” hasta “Nonillion”): Terminos (Ind_G) = “ “ + v_Pref_1(Ind_G – 1) + K_Suf_1 Índice Grupo Núm. Digitos Prefijo Sufijo Término 1 6 M illion Million 2 9 B Billion 3 12 Tr Trillion 4 15 Quadr Quadrillion … … … … 9 30 Non Nonillion Tabla T.6.5.A o Si es un grupo entre los dígitos 33 y 60 (desde “Decillion” hasta “Novendecillion”): Si el Resto de dividir Ind_G entre 10 es igual a 0: Terminos(Ind_G) = “ “ + v_Pref_2(0) + K_Suf_1 Si no: Terminos (Ind_G) = “ “ + v_Pref_3(Resto(Ind_G/10) – 1) + v_Pref_2((Ind_G/10) – 1) + K_Suf_1 Índice Grupo Núm. Digitos Prefijo Sufijo Término 10 33 Dec illion Decillion 11 36 Un + Dec Undecillion 12 39 Duo + Dec Duodecillion
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 67 de 72 13 42 Tre + Dec Tredecillion … … … … 19 60 Noven + Dec Novendecillion Tabla T.6.5.B o Si es un grupo entre los dígitos 63 y 300: Si el Resto de dividir Ind_G entre 10 es igual a 0: Terminos (Ind_G) = “ “ + v_Pref_2((Ind_G/10) – 1) + K_Suf_2 Si no: Terminos (Ind_G) = “ “ + v_Pref_4(Resto(Ind_G/10) – 1) + v_Pref_2((Ind_G/10) – 1) + K_Suf_2 Índice Grupo Núm. Dígitos Prefijo Sufijo Término 20 63 Vi gintillion Vigintillion 21 66 Un + Vi Unvigintillion 22 69 Duo + Vi Duovigintillion 23 72 Tre + Vi Trevigintillion … … … … 99 300 Noven + Nona Novennonagintillion Tabla T.6.5.C o Si el grupo se corresponde con el dígito 303 (“Centillion”): Terminos (Ind_G) = “ “ + K_Cent. Centillion NOTAS: Terminos es el nombre del array que se devuelve. Ind_G es el índice de un elemento en el array, comenzando desde 0. Estos son los términos empleados en Escala Corta. Para la Escala Larga, se utiliza el mismo array, pero entre medio de cada par de términos se introduce uno igual al primero de ellos cambiando el sufijo “-illion” por “-illiard”: Thousand (3) Million (6) Milliard (9) Billion (12) Billiard (15) Trillion (18) Trilliard (21) Quadrillion (24) Quadrilliard (27) … Tabla T.6.5.D
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 68 de 72 6.6. Integración de resultados. Como vimos en el apartado sobre concurrencia, la obtención independiente de resultados parciales por parte de cada tarea nos lleva inexorablemente a una integración de resultados que dará lugar al conjunto definitivo. La función Integrar_Resultados se encarga de integrar y combinar los resultados parciales obtenidos y devolverlos en un único conjunto, a través de una instancia de la clase Res_Def (Resultados Definitivos). El algoritmo que implementa esta función es el siguiente: Se inicializan variables, entre ellas la de almacenamiento de los resultados definitivos, que será devuelta por la función. Si el número es no fraccionario: o Para cada resultado de la parte entera: Si hay errores, se incluyen en la lista de errores definitiva y se pasa al siguiente resultado. Se obtiene el resultado y la categoría a la que pertenece. Si el número es negativo, se antepone la palabra “negative” si la categoría corresponde a inglés americano, o “minus” si corresponde a inglés británico. Para cada resultado de la parte decimal (si la hay): Si hay errores, se incluyen en la lista de errores definitiva y se pasa al siguiente resultado. Se obtiene el resultado y la categoría a la que pertenece. Si la categoría de la parte decimal es “con punto”, se concatena la parte entera con la parte decimal y se inserta como resultado definitivo. Si la categoría de la parte decimal es “sin punto” y la
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 69 de 72 categoría de la parte entera no es de inglés británico (que ya utiliza “and” y por tanto no se puede concatenar), también se concatena e inserta como resultado definitivo. Si no hay parte decimal, simplemente se inserta el resultado como definitivo. Si el número es fraccionario: o Para cada resultado del numerador: Si hay errores, se incluyen en la lista de errores definitiva y se pasa al siguiente resultado. Se obtiene el resultado y la categoría a la que pertenece. Si el número es negativo, se antepone la palabra “negative” si la categoría corresponde a inglés americano, o “minus” si corresponde a inglés británico. Para cada resultado del denominador: Si hay errores, se incluyen en la lista de errores definitiva y se pasa al siguiente resultado. Se obtiene el resultado y la categoría a la que pertenece. Si la combinación Numerador - Denominador no es válida, por tener formatos incompatibles, se descarta y se pasa al siguiente resultado. Si el denominador es 2 o 4, se añaden, excepcionalmente, nuevos resultados alternativos empleando los términos “half” o “quarter” respectivamente.
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 70 de 72 Si el denominador es mayor que 1, se concatena una “s” por la derecha al resultado. Si la categoría es de inglés británico, se concatena un “and” o “and a” entre numerador y denominador. Si no, simplemente se concatena un espacio entre ambos. Finalmente se devuelven los resultados definitivos. En el caso de que existan resultados fraccionales y no fraccionales, se devuelven ambos. 6.7. Mejora de rendimiento a través de la clase StringBuilder. Los objetos de tipo String son invariables. Esto quiere decir que cada vez que se usa uno de sus métodos, se crea un nuevo objeto de cadena en la memoria, que necesita una nueva asignación de espacio para dicho objeto. Esta circunstancia hace que en los casos en que sea necesario hacer repetidas modificaciones en una cadena, la sobrecarga asociada a la creación de un nuevo objeto String pueda disminuir el rendimiento. Por su parte, la clase StringBuilder permite modificar una cadena sin crear un nuevo objeto, y por ello puede mejorar considerablemente el rendimiento al concatenar muchas cadenas en un bucle. Es por ello que en nuestro caso, donde precisamente necesitamos realizar continuas concatenaciones, se hace altamente recomendable utilizar objetos StringBuilder para obtener un rendimiento óptimo. Uno de los puntos críticos del código en este sentido es en el método Editar de la clase Res_Par, donde se producen las concatenaciones de los resultados parciales, y por ello empleamos una lista de tipo StringBuilder.
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 71 de 72 7. CONCLUSIONES Y TRABAJOS FUTUROS. En vista de todo lo expuesto, se pueden obtener las siguientes conclusiones: La escritura de números con palabras en el idioma inglés es un proceso sistemático, aunque con determinadas excepciones. En la actualidad existen dos corrientes claramente diferenciadas: el inglés británico y el inglés americano, cada una de ellas con sus peculiaridades. Dichas peculiaridades, como por ejemplo el uso de escala corta o escala larga, dan lugar a que un mismo número pueda ser escrito de distintas formas. Aunque los términos que se emplean para la designación de números constituyen un conjunto finito, éstos permiten referirse hasta números extremadamente grandes, prácticamente inmanejables para el ser humano. Si como es de esperar, esta utilidad tiene una aceptación similar a la ya desarrollada para la conversión a texto en español, sería más que razonable considerar la idea de extenderla a otros idiomas, especialmente a los más hablados en el mundo, como francés, alemán, etc. 8. FUENTES DE INFORMACIÓN. La información recopilada en este documento ha sido obtenida a partir de las siguientes fuentes: Numbers in academic writing: https://www.une.edu.au/__data/assets/pdf_file/0012/10803/WC_Numb ers-in-academic-writing.pdf House Style (Oxford University Press): http://global.oup.com/uk/academic/authors/AuthorGuidelinesMain/Hou seStyle/#lev19
Trabajo de Fin de Grado: Conversor de números a texto en Inglés Página 72 de 72 Numbers and dates (Oxford Dictionaries): http://www.oxforddictionaries.com/secondary/harts_rules/11-1numbers-general-principles English numerals (Wikipedia): http://en.wikipedia.org/wiki/English_numerals Generador de números ordinales y cardinales en ingles (hasta 66 dígitos): http://www.ego4u.com/en/cram-up/vocabulary/numbers/generator Numbers Vocab (EnglishClub): https://www.englishclub.com/vocabulary/numbers.htm Names of large numbers: http://en.wikipedia.org/wiki/Names_of_large_numbers English names of the first 10000 powers of 10: http://www.isthe.com/chongo/tech/math/number/tenpowere.html Ordinal Numbers: http://www.ego4u.com/en/cramup/vocabulary/numbers/ordinal Name of Decimals: http://www.aaamath.com/nam.htm#topic8 Read and Write Decimals: http://www.mathgoodies.com/lessons/decimals/read_write.html Introduction to Decimals: http://cstl.syr.edu/fipse/Decunit/intrdec/intrdec.htm Lenguaje de expresiones regulares: https://msdn.microsoft.com/eses/library/az24scfc%28v=vs.110%29.aspx Paralelismo de tareas: https://msdn.microsoft.com/eses/library/dd537609%28v=vs.110%29.aspx Utilizar la clase StringBuilder en NET.Framework: https://msdn.microsoft.com/eses/library/2839d5h5%28v=vs.110%29.aspx