NaN, proviene del acrónimo en inglés «Not a Number» (en español: no es un número). Este acrónimo se usa generalmente en algunos lenguajes de programación para expresar un resultado imposible de calcular, como el caso de las raíces negativas, indeterminaciones, etc., retornando NaN como resultado de la operación.
NaN en los enteros
La mayoría de los formatos de representación de enteros no posee una forma de indicar la invalidez de los datos. El paquete de perl que indica el entero más grande (BigInt), usa el valor de NaN para los resultados de transformación de cadenas que no sean representables como enteros.
perl -mMath::BigInt -e "print Math::BigInt->new('foo')" NaN
NaN en coma flotante
En las operaciones de coma flotante, NaN no es lo mismo que infinito, ya que ambos son tratados como casos especiales en las representaciones de coma flotante para números reales, así como en las operaciones. Una operación inválida no es lo mismo que un overflow aritmético (que podría retornar infinito tras la operación) o un underflow aritmético (que puede retornar el número más pequeño que se puede representar).
Según la norma IEEE 754, los casos de NaN se pueden representar rellenando el campo de exponente con unos y la mantisa con algunos números diferentes de cero. Un ejemplo de esta representación con precisión simple sería:
con x como cualquier número. Sí a es 1 es un NaN con dígito 1, sino es un signo. Un valor de NaN no es posible compararlo con algún número de coma flotante, a menos que posea una representación idéntica.
En el estándar de la IEEE se establece que las operaciones aritméticas que involucran un NaN producen un NaN, permitiendo que este valor pueda propagarse a través de los cálculos. En la propuesta de revisión del estándar (IEEE 754r), se establecen varias excepciones a esta regla, incluyendo la implementación de las funciones maxnum y minnum, que permiten el retorno de los valores mínimos y máximos de un operador y el número en caso de una evaluación conjunta entre un número y el valor NaN. Esta modificación es útil en las operaciones de estadística donde hay datos con valores desconocidos.
Un concepto similar ha sido implementado en NaN toolbox para GNU Octave y MATLAB. En ambos programas, NaN posee un significado diferente y representa valores desconocidos. El NaN Toolbox posee funciones estadísticas que ignoran cualquier valor de NaN en los datos, evitando la propagación de este resultado. La mayoría de los algoritmos se basan en la función SUMSKIPNAN,[1] cual suma y cuenta todos los datos que toman valores de NaN.
Operaciones que crean NaN
Los siguientes casos pueden generar el estado de NaN en la mayoría de los lenguajes de programación que acepten este estado como retorno de una función matemática:
- Todas las operaciones matemáticas que posean NaN como operando matemático.
- Las divisiones indeterminadas o por infinito (0/0, ∞/∞, ∞/-∞, -∞/∞)
- Las multiplicaciones de 0 por infinito (0×∞, 0×-∞)
- Las restas de valores infinitos (∞ -∞)
- Aplicando funciones que excedan el dominio de la misma. Por ejemplo, la raíz cuadrada de un número negativo, logaritmo de cualquier número menor o igual que 0, o la inversa de un coseno que sea menor que -1 o mayor que +1.
Sin embargo, es importante destacar que los resultados NaN no son necesariamente generados por el procesador. En el caso de los NaN con dígito 1, el primer elementos siempre es válido para cada procesador, en el resto no necesariamente lo es. Por ejemplo, en la arquitectura Intel, la Unidad de Coma Flotante nunca crea una excepción de NaN en el primer caso. En los otros casos puede generar excepciones, pero no NaN. Sin embargo, el software que determina las excepciones puede examinar los operadores y decidir si retorna el estado NaN.
Tipos de NaN
Existen dos tipos de NaN, que se diferencian por las consecuencias que trae la indeterminación de la operación, generando o no excepciones adjuntas a la operación que resulta con el valor de NaN.
NaN simple
NaN simple (en inglés, quiet NaN) son las operaciones que no generan otras excepciones adicionales para ser propagadas a través de todas las operaciones. Las excepciones que se asocian a NaN no pueden ser pasados al usuario sin ser convertido o posee ciertas conversiones para ser utilizados, como por ejemplo, el ingreso no permitido en javascript, genera valores de NaN.
NaN señalizados
NaN señalizado (en inglés, Signalling NaN) son formas especial de NaN cuando se genera el problema y debe generarse una excepción de invalidez de la operación y, si es necesario, prosigue la operación mediante un NaN simple. Fue introducido en el estándar IEEE 754. Debido a su gran libertad de definición, se puede usar el valor de NaN en los siguientes casos, que dependen directamente del lenguaje de programación:
- Llenado de memoria sin inicializar con NaN señalizados puede producir una excepción inválida si los datos son usados antes de su asignación de valor.
- Uso de NaN señalizados como parte de objetos más complicados como:
- un número que posee un underflow u overflow.
- un número en un formato de precisión mayor al admitido.
- un número complejo.
Cuando se encuentra este valor de NaN, se puede retornar un índice al resultado obtenido. En la práctica, esta aproximación posee varias complicaciones. El tratamiento del bit de signo del valor NaN para operaciones simples, como el valor absoluto, es diferente a las operaciones aritméticas normales.
NaN en las funciones
Hay varias formas de abarcar el problema de poseer una definición adecuada para el resultado de una función numérica que recibe un NaN simple como argumento de función.
Un punto de vista es que el valor de NaN debe propagarse al retorno de función en todos los casos para indicar la presencia de error. El otro punto de vista sugiere que si la función posee múltiple argumentos de entrada y el retorno se determina únicamente por las entradas que son distinta a NaN, entonces el retorno debe ser el valor obtenido como resultado.
En resumen, existiría la siguiente disyuntiva, si programamos la siguiente función
function multiplicar(x, y) return x * y;
Si uno de los argumentos es NaN, entonces se puede realizar los retornos, según lo que estime el programador. Puede retornar el valor de la variable no NaN o retornar, por el principio de propagación de valores, el valor de NaN. El primer enunciado es el más utilizado en las funciones matemáticas, realizando la operación que corresponda y evaluando los valores de retorno.
Otro punto de vista que se puede establecer para pruebas es que
(x <= infinito)
que es verdadero para cualquier valor real de x. Pero en el estándar IEEE 754 (NaN <= infinito) es falso.
Referencias
- Traducción libre desde el artículo NaN, que se encuentra disponible en Wikipedia en inglés.