2.2. Soporte de aritmética decimal para sistemas de computación
2.2.1. Soporte software
Muchos lenguajes de programación incluyen tipos de datos primitivos decimal. Tal caso de Ada [ISO01], .NET Framework (C# [ISO03], Visual Basic [Mic11]), COBOL [ANS02], PL/I [ANS76] y SQL [ISO92].
Existen otros lenguajes que se adhieren al General Decimal Arithmetic Specifications [Cow09] (GDAS) desarrollado por Mike Cowlishaw. Esta especificación se basa en el estándar IEEE 854-1987 [IEEE87], y forma la base de las especificaciones de aritmética decimal detalladas en el estándar IEEE 754-2008 [IEEE08] (sección 2.3). De este modo, los lenguajes que soportan GDAS operan conformes al estándar IEEE 754-2008. Varios lenguajes ofrecen librerías con soporte según GDAS: IBM C DecNumber [Cow10], Java Big Decimal [Sun17] [IBM03], Lua decNumber [Cur07], Phyton Decimal [Bat03], Eiffel Decimal Artithmetic [Cri04] y Rexx [ANS96].
Compiladores como C y C++ incorporaron extensiones para el soporte DFP conforme a IEEE 754-2008 [ISO15] [ISO17] [FSF08]. Por su parte Intel, desarrolló una librería matemática en C, que implementa aritmética DFP según estándar IEEE 754- 2008 con mantisa codificada en binario (sección 2.3) [Cor07].
Muchos compiladores utilizan las instrucciones hardware DFP sujetas al estándar IEEE 754-2008 sobre las plataformas IBM Power6 [Eis07] y Power 7 [Wen10], e IBM System z9 [Dua07] y z10 [Sch09]. Tal es el caso de GCC (GNU Collection Compiler) [FSF17], IBM XL C/C++ [IBM17], IBM Enterprice PL/I [IBM07a], IBM DB2 [IBM07b], IBM High-level Assembler [IBM15], IBM DFPAL [IBM07c], etc.
2.2.2. Soporte hardware
Algunas de las primeras computadoras electrónicas, tales como ENIAC [Gol96], UNIVAC [Hea01] e IBM 650 [Knu86], realizaban sus funciones aritméticas en base diez. Aún con la llegada de las computadoras basadas en transistores de dos estados, se continuaban fabricando computadoras que procesaban datos en base diez mediante la codificación de cada dígito decimal en BCD. Sin embargo, con motivo de generalizar todo tipo de aplicación, ya sean tanto comerciales como científicas, y debido al incremento de la demanda de cálculos científicos rápidos, emergió y prevaleció la aritmética binaria.
Más recientemente, varios microprocesadores comerciales ofrecen instrucciones para aritmética BCD en punto fijo. Tal es el caso de los procesadores pertenecientes a las series x86 de Intel [Int01a], 68k de Motorola [Mot92] y HP PA-RISC [Kan96].
Los mainframes de IBM poseen un soporte más completo y extenso de hardware en aritmética decimal. En S/390 [IBM08] las operaciones básicas en punto fijo decimal, como suma, resta, multiplicación y división, mediante la utilización de la suma decimal directa. La plataforma System z9000 [Bus01] efectúa las mismas operaciones en punto fijo decimal mediante el empleo de sumadores decimal/binario combinados.
Por otro lado, los mainframes IBM Power6 [Eis07] y Power 7 [Wen10], e IBM System z9 [Dua07] y z10 [Sch09], proveen instrucciones con soporte de aritmética DFP conforme al estándar IEEE 754-2008.
La corporación SilMinds (www.silminds.com) comercializa núcleos (cores) sintetizables escritos en VHDL y Verilog que efectúan operaciones de suma, resta, multiplicación, división y raíz cuadrada conforme al estándar IEEE 754-2008. Los cores que ofrece SilMinds no solo están destinados para el desarrollo de procesadores comerciales o ASICs, sino que también al desarrollo de sistemas basados en FPGAs.
2.3. Estándar IEEE 754-2008
El estándar para aritmética de punto flotante IEEE 754-2008 [IEEE08], es un producto del Floating Point Working Wroup de IEEE Computer Society. El estándar provee mecanismos, normativas y reglas para realizar computación en punto flotante decimal y binario. Especifica formatos y métodos, tales como funciones estándares y extendidas con precisiones simple, doble, extendida y extendible, y además recomienda formatos de intercambio. También se definen las condiciones de excepciones así como su tratamiento.
El propósito de este estándar es proveer métodos para el cómputo de números en punto flotante, de modo que ante los mismos datos de entrada, se obtienen los mismos resultados independientemente si el procesamiento se realiza en hardware, en software, o en ambos.
La existencia de un estándar para aritmética de computadoras beneficia tanto a los desarrolladores de hardware, como a los desarrolladores de software y también a los usuarios finales. Los desarrolladores de hardware tienen confianza de sus implementaciones, las cuales ofrecen las mismas soluciones que implementaciones de otros desarrolladores. Pero cuando implementan una función estándar específica, pueden comparar el rendimiento de su solución con la de otros para determinar su competitividad. Por otro lado, un estándar le permite a los desarrolladores de software, realizar códigos portables para sistemas compatibles y obtener resultados consistentes. En cuanto a los usuarios finales, ellos pueden migrar sus datos de una plataforma a otra, posibilitando que no se encuentren sujetos a un formato de almacenamiento propietario [Erl09].
Este estándar surge de la combinación y ampliación de los estándares para aritmética de punto flotante binario IEEE 754-1985 [IEEE85] y punto flotante de radix independiente IEEE 854-1987 [IEEE87]. El estándar IEEE 854-1987 carece de descripciones para los formatos de almacenamiento de números DFP. Otra limitación es que no está determinado si los operandos y resultados deben estar normalizados o no. Estas limitaciones llevaron a una moderada recepción por parte de la comunidad de usuarios y a la inclusión de aritmética DFP en una versión revisada del estándar IEEE 754-1985.
El estándar IEEE 754-1985 define cuatro formatos para representar números de punto flotante binario (BFP, Binary Floating Point), incluyendo el cero negativo, números subnormales, infinitos y NaN (Not a Number). Además define un conjunto de operaciones sobre esos valores BFP, un conjunto de cuatro modos de redondeo y cinco tipos de excepciones. Este estándar se extendió varias veces, hasta que en el año 2000 se impulsa la revisión del IEEE 754-1985 para actualizar el estándar. Una parte de esta revisión es la incorporación de DFP (con consideraciones del IEEE 854-1987 [IEEE87])
13 Luego de ocho años de borradores, revisiones y acuerdos, en Agosto del 2008 surge el estándar IEEE 754-2008 [IEEE08]. Éste define cinco formatos de números de punto flotante (tres binarios y dos decimales), así como también formatos de intercambio decimal y binario. Además define cinco modos de redondeo y cinco tipos de excepciones con sus respectivos tratamientos.
El resto de esta sección describe los aspectos más significativos del estándar vinculados a aritmética DFP.
2.3.1. Formatos decimales
El conjunto de números DFP representable en un formato en particular se define con los siguientes parámetros:
- b = 10, correspondiente a la base
- p es el número de dígitos de la mantisa (precisión) - emax el máximo exponente e
- emin el mínimo exponente e (con emin = 1- emax para todos los formatos) La tabla 2.2 muestra los valores de los parámetros para cada formato básico correspondiente a la base decimal (b = 10).
Tabla 2.2- Parámetros de los formatos básicos de números DFP.
Formatos Parámetro
decimal64 decimal128
p (dígitos) 16 34
emax 384 6144
El conjunto de datos de punto flotante representados es el siguiente: - números de punto flotante con signo, (-1)s
×10e×m, donde - s es el signo: 0 ó 1.
- e corresponde al exponente, con e∈Z∴emin≤e≤emax.
- m determina la mantisa, con m = d0.d1d2··dp-1 y di∈
{
0,1,..,9}
, (0≤m<10).- dos infinitos: ±∞
- dos NaNs: qNaN (quiet) y sNaN (signaling).
En la descripción anterior, la mantisa se expresa de forma científica, con el punto decimal después del primer dígito. Dependiendo de la aplicación, muchas veces es conveniente observar a la mantisa como un entero. Por lo anterior, una manera equivalente de "entender" los números de punto flotante finitos es (-1)s
×10q×c, donde - s es el signo: 0 ó 1.
- q∈Z∴emin≤q+p-1 ≤emax.
- c es un número entero con la forma c = d0d1··dp-1, con di∈
{
0,1,..,9}
, (0≤c<10Se define número normal como un número punto flotante decimal diferente a cero cuya magnitud es mayor o igual que 10emin. De este modo, un número normal
x se representa de la siguiente manera:
x = (-1)s×10e
×m,con m≥1 y e∈Z∴ emin≤e≤emax. o alternativamente (mantisa como entero):
x = (-1)s×10q×c,con q,c∈Z∴emin-(p-1)≤q ≤emax-(p-1) y c≥10p-1.
Por otro lado, un número subnormal se define como un número de punto flotante decimal diferente a cero, cuya magnitud es menor que 10emin. Por consiguiente, un
número subnormalx se representa de la siguiente manera: x = (-1)s×10emin
×m,con m<1, significa que d0=0.
o alternativamente (mantisa como entero), donde qmin = emin-(p-1): x = (-1)s×10qmin×c,con c<10p-1, significa que d0=0.
2.3.2. Formatos de Intercambio
El estándar especifica tres tipos de formatos de intercambio para números DFP: decimal32, decimal64 y decimal128. Cada formato está codificado en k bits y poseen tres campos: un campo de signo (S), un campo combinacional (G) y un campo de final de mantisa (T).
1 bit w+5 bits t = 10×J bits
S (signo)
G
(campo combinacional)
T
(campo final de mantisa)
G[0] .. G[w+4] 3J=p-1
En la tabla 2.3 se aprecia la cantidad de bits involucrados en cada campo para cada uno de los formatos. La tabla 2.4 muestra características, como cantidad de bits o rangos, de los parámetros involucrados en los distintos formatos de intercambio para números DFP.
Tabla 2.3 – Tamaño (bits) de los campos pertenecientes a los formatos de intercambio
de números de punto flotante decimal.
Campo decimal32 decimal64 decimal128
S 1 1 1
G 11 13 17
T 20 50 110
k 32 64 128
En el campo final de mantisa (T), se encuentran codificados los p-1 dígitos menos significativos correspondientes a la mantisa. Este campo posee Jdeclets (3J=p-1) de 10 bits cada uno, en los cuales el final de mantisa se encuentra codificado en decimal o
15
Tabla 2.4 – Parámetros de los formatos de intercambio de números DFP.
Parámetro decimal32 decimal64 decimal128
exponente (bits) 8 10 14
mantisa (dígitos) 7 16 34
bias de exponente 101 398 6176
e -95≤e≤96 -383≤e≤384 -6143≤e≤6144
q -101≤q≤90 -398≤q≤369 -6176≤q≤6111
Para la codificación decimal, se utiliza el formato desenly-packed decimal (DPD) para empaquetar 3 dígitos BCD en un declet. Para poder empaquetar tres dígitos en BCD (doce bits) en diez bits, este formato se basa en el aspecto que con 4 bits, existen varias codificaciones no usadas para la representación de un número decimal en BCD. Tanto la codificación de BCD a DPD como la decodificación de DPD a BCD son simples [Cow02].
El campo combinacional (de tamaño w+5 bits) determina cómo es el dato almacenado o representado, esto es si es un valor infinito, o un número punto flotante finito, o NaN. Para el caso en que se almacene un número finito, en este campo se encuentra además codificados el exponente y el dígito más significativo de la mantisa. En las tabas 2.5 y 2.6 se observa como se decodifican los números DFP a partir de campo combinacional.
Tabla 2.5 – Interpretación de campo combinacional (clasificaciones especiales)
G[0..4] G[5..w+4] T Dato representado
11111 1x..x -- qNaN
11111 0x..x -- sNaN
11110 0..0 0..0 ±∞
Obsérvese que un número punto flotante decimal puede tener múltiples representaciones. Al conjunto de representaciones para un número punto flotante determinado se lo denomina cohortedel número. Por ejemplo, si c es múltiplo de 10 y q es menor al valor máximo permitido, entonces (s, q, c) y (s, q+1, c/10) son dos representaciones del mismo número punto flotante pertenecientes al mismo cohorte.
Tabla 2.6 – Interpretación de campo combinacional (números de punto flotante finito)
Codif. de
mantisa G[0..4] Exponente Mantisa (m=d0..dp-1)
0xxxx ó 10xxx G[0]&G[1]&G[5..w+4] – bias d0 = 4G[2] + 2G[1] + G[0] d1..dp-1 = DPDtoBCD(T)
Decimal
110xx ó 1110x G[2]&G[3]&G[5..w+4] – bias d0 = 8 + G[4]
d1..dp-1 = DPDtoBCD(T)
Nota 1: x significa que puede tomar tanto el valor 0 como 1.
Nota 2: el símbolo “&” significa “concatenado con”.
2.3.3. Excepciones
El estándar especifica cinco tipos de excepciones que se indican cuando suceden. Esta indicación invoca al manejo, por defecto o alternativo, de la correspondiente excepción identificada. La implementación debe proveer el correspondiente flag de estado para cada tipo de excepción.
A continuación se detallan los cinco tipos de excepciones:
- Operación inválida: se indica cuándo no existe ningún resultado definible por el estándar. En este caso, los operandos son inválidos para la operación que se desea realizar. Ejemplos: ∞-∞, ∞×0, ∞/∞, etc.
- División por cero: se indica cuando un resultado infinito se produce por una operación entre operandos finitos.
- Overflow: cuando se excede en magnitud al número finito más grande.
- Underflow: si el resultado es diferente a cero y se encuentra estrictamente entre ±bemin.
- Inexacta:si el resultado redondeado de una operación requiere de una precisión mayor a la soportada por el formato de representación utilizado.
2.3.4. Redondeo
Este estándar define cinco tipos de redondeo que pueden ser seleccionados por el usuario mediante el correspondiente seteo de atributos:
- RoundTiesToEven: se escoge la representación más cercana al resultado obtenido. Si dos representaciones se encuentran igualmente cerca, se escoge aquella cuyo dígito menos significativo sea par.
- RoundTiesToAway: se escoge la representación más cercana al resultado obtenido. Si dos representaciones se encuentran igualmente cerca, se escoge la de mayor magnitud.
- RoundTowardPositive: se escoge la representación más cercana mayor al resultado obtenido.
- RoundTowardNegative: se escoge la representación más cercana menor al resultado obtenido.
- RoundTowardZero: se escoge la representación más cercana menor en magnitud al resultado obtenido.