# Número subnormal

En informática, los números denormales, desnormalizados, no normales o subnormales son números que llenan el vacío de subdesbordamiento (underflow) en las proximidades del cero en aritmética de punto flotante. Cualquier número distinto de cero con una magnitud menor que el menor número normal es 'subnormal'.
En un valor de punto flotante normal, no hay ceros principales en la mantisa; en cambio, los ceros principales se mueven al exponente. Así 0.0123 se escribiría como 1.23 × 10$^{−2}$. Los números denormales son números donde esta representación daría lugar a un exponente que está por debajo del exponente mínimo (generalmente el exponente que tiene un rango limitado). Tales números se representan mediante ceros principales en la mantisa.
La mantisa de un número de punto flotante IEEE es la parte de un número de punto flotante que representa los dígitos significativos. Para un número normalizado positivo puede ser representado como m$_0$.m$_1$m$_2$m$_3$...m$_{p-2}$m$_{p-1}$ (donde m representa un número significativo y p es la precisión, y m0 es distinto de cero). Note que para un radix binario, el dígito binario líder siempre es 1. En un número denormal, como el exponente es lo menor que puede ser, el cero es el primer dígito significativo (0.m$_1$m$_2$m$_3$...m$_{p-2}$m$_{p-1}$), lo que permite la representación de los números más cerca de cero que el número normal más pequeño.
Al llenar el vacío de subdesbordamiento (underflow) de esta manera, los dígitos significativos se pierden, pero no tan abruptamente como al utilizar el flush to zero en la aproximación de underflow (descartando todos los dígitos significativos cuando se alcanza el subdesbordamiento). Por lo tanto la producción de un número denormal a veces se llama subdesbordamiento gradual, ya que permite un cálculo para perder precisión lentamente cuando el resultado es pequeño.
En IEEE 754-2008, los números denormales se renombran números subnormales, y son compatibles con ambos formatos binarios y decimales. En formatos de intercambio binarios, los números subnormales están codificados con un exponente sesgado de 0, pero se interpretan con el valor del exponente permitido más pequeño, que es uno mayor (es decir, como si se codificara como un 1). En formatos de intercambio decimales que no requieren codificación especial porque el formato apoya directamente a los números no normalizados
Matemáticamente hablando, los números de punto flotante normalizados de un signo dado, son más o menos espaciados logarítmicamente, y como cualquier flotante normal de tamaño finito, no pueden incluir ceros. Los flotantes denormales son un conjunto linealmente espaciado de valores que cubren la brecha entre los flotantes normales negativos y positivos

## Antecedentes

Números denormales proporcionan la garantía de la suma y resta de números de punto flotante sin subdesbordamientos; dos números de punto flotante cercanos siempre tienen una diferencia representable distinta de cero. Sin desbordamiento gradual, la sustracción a-b puede dar subdesbordamiento y producir cero a pesar de que los valores no son iguales. Esto puede, a su vez, dar lugar, en la división por cero, a errores que no se pueden producir cuando se usa desbordamiento gradual.
Los números denormales se implementaron en el Intel 8087, mientras el estándar IEEE 754 se estaba escribiendo. Eran, por mucho, el aspecto más controvertido de la propuesta de formato de K-C-S que finalmente se adoptó, pero esta aplicación demostró que los denormales podrían utilizarse en una aplicación práctica. Algunas implementaciones de unidades de punto flotante no apoyan directamente los números denormales en hardware, sino más bien los simulan mediante algún tipo de soporte de software. Aunque esto puede ser transparente para el usuario, puede originar cálculos que producen o consumen los números denormales y son mucho más lentos que los cálculos similares con números normales.

## Rendimiento

Algunos sistemas manejan los valores denormales en hardware de la misma manera que los valores normales. Otros dejan el manejo de valores denormales al software del sistema y solo manejan ceros y valores normales en hardware. Manejar los valores denormales en el software siempre genera una disminución significativa en el rendimiento. Cuando se calculan los valores denormales en hardware, existen técnicas de implementación para dejar su procesamiento en las velocidades comparables a las de los números normales; aun así, la velocidad de computación es significativamente menor sobre muchos de los procesadores modernos; en casos extremos, las instrucciones que implican los operandos denormales pueden correr 100 veces más lento.
Esta diferencia de velocidad puede ser un riesgo de seguridad. Los investigadores mostraron que proporciona un canal lateral de tiempo que permite a un sitio web malicioso extraer contenido de otro sitio web dentro de un navegador.
Algunas aplicaciones necesitan encapsular código para evitar números denormales, para mantener exactitud o para evitar la penalización de rendimiento en algunos procesadores. Por ejemplo, en las aplicaciones de procesamiento de audio, los valores denormales generalmente representan una señal tan suave que está fuera de la gama de oído humana. Debido a esto, una medida común para evitar valores denormales en procesadores, donde habría una penalización de rendimiento, es cortar la señal a cero una vez que alcanza niveles denormales o mezclar en una señal de ruido extremadamente silencioso. Otros métodos de prevención de los números denormales son añadir un desplazamiento DC, cuantificando los números, la adición de una señal de Nyquist, etc. Desde la extensión del procesador SSE2, Intel ha proporcionado tal funcionalidad en CPU, que redondea números denormales a cero.

## Desactivación de flotantes denormales a nivel de código

El lenguaje C de Intel y los compiladores de Fortran habilitan los cero denormales (Denormals Are Zero, DAZ) y las banderas a ras de cero (flush-to-zero, FTZ) para SSE por defecto en los niveles de optimización superiores -O0. El efecto de DAZ es tratar argumentos denormales de entrada a operaciones de punto flotante como cero y el efecto de FTZ es devolver cero en vez de un flotante denormal en operaciones que resultarían en un flotante denormal, incluso si los argumentos de entrada no son denormales por sí mismos. Clang y gcc tienen diferentes estados predeterminados dependiendo del nivel de la plataforma y la optimización. A continuación se da un método, no C99-compatible, de permitir las banderas DAZ y de FTZ en los objetivos de apoyo SSE, pero no es ampliamente apoyado. Se sabe que funciona en Mac OS X desde al menos 2006.
Para otras plataformas de instrucciones SSE-establecidos no se ha implementado la bandera anterior en la biblioteca de C, lo siguiente puede funcionar:
Generalmente se recomienda utilizar el macro _MM_SET_DENORMALS_ZERO_MODE porque evitará sobrescribir cualquier otra configuración en el CSR.
La mayoría de los compiladores ya proporcionan el anterior macro por defecto; en cualquier caso, puede utilizarse el siguiente fragmento de código:
Ambos métodos deben realizarse sobre la base de hilos. Al utilizar esquemas de paralelismo basados en tareas (como en Grand Central Dispatch), cuando la aplicación tiene poco o ningún control sobre el hilo que está ejecutando una tarea determinada, esto puede requerir la desactivación explícita de valores denormales al comienzo de cada tarea.