En informática , NaN ( / n æ n / ), que significa Not a Number , es un miembro de un tipo de datos numéricos que puede interpretarse como un valor indefinido o irrepresentable, especialmente en aritmética de punto flotante . El uso sistemático de NaN fue introducido por el estándar de punto flotante IEEE 754 en 1985, junto con la representación de otras cantidades no finitas como los infinitos .
En matemáticas , cero dividido por cero no está definido como un número real y, por lo tanto, está representado por NaN en los sistemas informáticos. La raíz cuadrada de un número negativo no es un número real y, por lo tanto, también está representada por NaN en los sistemas informáticos compatibles. Los NaN también se pueden utilizar para representar valores perdidos en los cálculos. [1] [2]
Se proporcionan dos tipos distintos de NaN, denominados NaN silenciosos y NaN de señalización . Los NaN silenciosos se utilizan para propagar errores resultantes de operaciones o valores no válidos. Los NaN de señalización pueden admitir funciones avanzadas como la combinación de cálculos numéricos y simbólicos u otras extensiones de la aritmética básica de punto flotante.
Punto flotante
En los cálculos de punto flotante, NaN no es lo mismo que infinito , aunque ambos se manejan típicamente como casos especiales en representaciones de punto flotante de números reales, así como en operaciones de punto flotante. Una operación no válida tampoco es lo mismo que un desbordamiento aritmético (que podría devolver un infinito) o un subdesbordamiento aritmético (que devolvería el número normal más pequeño , un número denormal o cero ).
Los IEEE 754 NaN se codifican con el campo exponente lleno de unos (como valores infinitos) y algún número distinto de cero en el campo significativo (para diferenciarlos de los valores infinitos); esto permite la definición de múltiples valores de NaN distintos, dependiendo de qué bits se establezcan en el campo significand, pero también del valor del bit de signo inicial (pero no se requiere que las aplicaciones proporcionen una semántica distinta para esos valores de NaN distintos).
Por ejemplo, un NaN de precisión simple IEEE 754 bit a bit (32 bits) sería
s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
donde s es el signo (se ignora con mayor frecuencia en las aplicaciones) y la secuencia x representa un número distinto de cero (el valor cero codifica infinitos). El primer bit de x se utiliza para determinar el tipo de NaN: "NaN silencioso" o "NaN de señalización". Los bits restantes codifican una carga útil (la mayoría de las veces se ignora en las aplicaciones).
Las operaciones de coma flotante distintas de las comparaciones ordenadas normalmente propagan un NaN silencioso ( qNaN ). La mayoría de las operaciones de coma flotante en un NaN de señalización ( sNaN ) señalan la excepción de operación no válida; la acción de excepción predeterminada es entonces la misma que para los operandos qNaN y producen un qNaN si producen un resultado de punto flotante.
La propagación de NaN silenciosos mediante operaciones aritméticas permite detectar errores al final de una secuencia de operaciones sin realizar pruebas exhaustivas durante las etapas intermedias. Por ejemplo, si uno comienza con un NaN y agrega 1 cinco veces seguidas, cada adición da como resultado un NaN, pero no es necesario verificar cada cálculo porque uno puede simplemente notar que el resultado final es NaN. Sin embargo, según el lenguaje y la función, los NaN se pueden eliminar silenciosamente de una cadena de cálculos donde un cálculo en la cadena daría un resultado constante para todos los demás valores de punto flotante. Por ejemplo, el cálculo x 0 puede producir el resultado 1, incluso donde x es NaN, por lo que verificar solo el resultado final ocultaría el hecho de que un cálculo antes de x 0 dio como resultado un NaN. En general, entonces, se necesita una prueba posterior para detectar un conjunto de indicadores no válidos para detectar todos los casos en los que se introducen NaN [3] (consulte la definición de función a continuación para obtener más detalles).
En la sección 6.2 del antiguo estándar IEEE 754-2008 , hay dos funciones anómalas (las funciones maxNum
y minNum
, que devuelven el máximo de dos operandos que se espera que sean números) que favorecen los números; si solo uno de los operandos es un NaN, entonces se devuelve el valor del otro operando. La revisión IEEE 754-2019 ha reemplazado estas funciones ya que no son asociativas (cuando aparece un NaN de señalización en un operando). [4] [5]
Comparación con NaN
Una comparación con un NaN siempre devuelve un resultado desordenado incluso cuando se compara consigo mismo. Los predicados de comparación son señalización o no señalización en operandos NaN silenciosos; las versiones de señalización señalan la excepción de operación no válida para tales comparaciones. Los predicados de igualdad y desigualdad no son señalizadores, por lo que x = x que devuelve falso se puede usar para probar si x es un NaN silencioso. Los otros predicados de comparación estándar son todos señalizadores si reciben un operando NaN. El estándar también proporciona versiones sin señalización de estos otros predicados. El predicado determina si un valor es un NaN y nunca indica una excepción, incluso si x es un NaN de señalización.isNaN(x)
Comparación | NaN ≥ x | NaN ≤ x | NaN> x | NaN < x | NaN = x | NaN ≠ x |
---|---|---|---|---|---|---|
Resultado | Siempre falso | Siempre falso | Siempre falso | Siempre falso | Siempre falso | Siempre cierto |
Operaciones que generan NaN
Hay tres tipos de operaciones que pueden devolver NaN: [6]
- La mayoría de las operaciones con al menos un operando NaN.
- Formas indeterminadas :
- Las divisiones (± 0) / (± 0) y (± ∞) / (± ∞) .
- Las multiplicaciones (± 0) × (± ∞) y (± ∞) × (± 0) .
- Resto x % y cuando x es infinito o y es cero.
- Las sumas (+ ∞) + (−∞) , (−∞) + (+ ∞) y sustracciones equivalentes (+ ∞) - (+ ∞) y (−∞) - (−∞) .
- La norma tiene funciones alternativas para potencias:
- La
pow
función estándar y la función de exponente enteropown
definen 0 0 , 1 ∞ y ∞ 0 como 1 . - La
powr
función define las tres formas indeterminadas como operaciones no válidas y, por lo tanto, devuelve NaN.
- La
- Operaciones reales con resultados complejos , por ejemplo:
- La raíz cuadrada de un número negativo.
- El logaritmo de un número negativo.
- El seno inverso o el coseno inverso de un número menor que -1 o mayor que 1.
Los NaN también se pueden asignar explícitamente a variables, generalmente como una representación de valores perdidos. Antes del estándar IEEE, los programadores solían usar un valor especial (como -99999999) para representar valores no definidos o faltantes, pero no había garantía de que se manejaran de manera consistente o correcta. [1]
Los NaN no se generan necesariamente en todos los casos anteriores. Si una operación puede producir una condición de excepción y las trampas no están enmascaradas, la operación provocará una trampa en su lugar. [7] Si un operando es un NaN silencioso, y tampoco hay un operando NaN de señalización, entonces no hay una condición de excepción y el resultado es un NaN silencioso. Las asignaciones explícitas no causarán una excepción incluso para la señalización de NaN.
Silencio NaN
Los NaN silenciosos, o qNaN, no generan ninguna excepción adicional, ya que se propagan a través de la mayoría de las operaciones. Las excepciones son donde el NaN no puede simplemente pasar sin cambios a la salida, como en conversiones de formato o ciertas operaciones de comparación.
Señalización NaN
Los NaN de señalización, o sNaN, son formas especiales de un NaN que, cuando son consumidas por la mayoría de las operaciones, deben generar la excepción de operación no válida y luego, si corresponde, "silenciarse" en un qNaN que luego puede propagarse. Fueron introducidos en IEEE 754 . Ha habido varias ideas sobre cómo se podrían utilizar:
- Llenar la memoria no inicializada con señalización de NaN produciría la excepción de operación no válida si los datos se utilizan antes de que se inicialicen
- Usar un sNaN como marcador de posición para un objeto más complicado , como:
- Una representación de un número que se ha desbordado
- Una representación de un número que se ha desbordado
- Número en un formato de mayor precisión
- Un numero complejo
Cuando se encuentra, un manejador de trampas podría decodificar el sNaN y devolver un índice al resultado calculado. En la práctica, este enfoque se enfrenta a muchas complicaciones. El tratamiento del bit de signo de NaN para algunas operaciones simples (como el valor absoluto ) es diferente del de las operaciones aritméticas. Las trampas no son requeridas por la norma. Hay otros enfoques para este tipo de problema que serían más portátiles.
Definición de función
Existen diferencias de opinión sobre la definición adecuada del resultado de una función numérica que recibe un NaN silencioso como entrada. Una opinión es que el NaN debería propagarse a la salida de la función en todos los casos para propagar la indicación de un error. Otro punto de vista, y el adoptado por las normas ISO C99 e IEEE 754-2008 en general, es que si la función tiene varios argumentos y la salida está determinada de forma única por todas las entradas que no son NaN (incluido el infinito), entonces ese valor debería ser el resultado. Así, por ejemplo, el valor devuelto por hypot(±∞, qNaN)
y hypot(qNaN, ±∞)
es + ∞.
El problema es particularmente agudo para la función de exponenciación = x y . Las expresiones 0 0 , ∞ 0 y 1 ∞ se consideran formas indeterminadas cuando ocurren como límites (al igual que ∞ × 0), y la cuestión de si el cero a la potencia cero debe definirse como 1 tiene opiniones divididas.pow(x, y)
Si la salida se considera indefinida cuando un parámetro no está definido, entonces pow(1, qNaN)
debería producir un qNaN. Sin embargo, las bibliotecas matemáticas normalmente devuelven 1 para cualquier número real y , e incluso cuando y es un infinito . De manera similar, producen 1 para incluso cuando x es 0 o un infinito. La razón para devolver el valor 1 para las formas indeterminadas fue que el valor de las funciones en puntos singulares se puede tomar como un valor particular si ese valor está en el límite del valor [ aclaración necesaria ] para todo menos una pequeña parte de una bola. alrededor del valor límite de los parámetros. La versión 2008 del estándar IEEE 754 dice que y ambos deben devolver 1, ya que devuelven 1 cualquier otra cosa que se use en lugar de NaN silencioso. Además, ISO C99 y, posteriormente, IEEE 754-2008, eligieron especificar = 1 en lugar de qNaN; la razón de esta elección se da en la lógica C: [8] "Generalmente, C99 evita un resultado NaN donde un valor numérico es útil. ... El resultado de es + ∞, porque todos los valores grandes de coma flotante positivos son pares enteros ".pow(1, y)
pow(x, 0)
pow(1, qNaN)
pow(qNaN, 0)
pow(−1, ±∞)
pow(−2, ∞)
Para satisfacer aquellos que deseen una interpretación más estricta de cómo la función de potencia debe actuar, los 2008 norma define dos funciones de energía adicionales: , donde el exponente debe ser un entero, y , que devuelve un NaN cada vez que un parámetro es un NaN o la exponenciación haría dar una forma indeterminada .pown(x, n)
powr(x, y)
Entero NaN
La mayoría de los formatos de números enteros de tamaño fijo no pueden indicar explícitamente datos no válidos. En tal caso, al convertir NaN a un tipo entero, el estándar IEEE 754 requiere que se señale una excepción de operación no válida . Por ejemplo, en Java , tales operaciones arrojan instancias de java.lang.ArithmeticException
. [9] En C , conducen a un comportamiento indefinido , pero si se admite el anexo F, la operación produce una excepción de punto flotante "no válido" (como lo requiere el estándar IEEE) y un valor no especificado.
El Math::BigInt
paquete de Perl usa "NaN" para el resultado de cadenas que no representan números enteros válidos. [10]
> perl -mMath :: BigInt -e "print Math :: BigInt-> new ('foo')" NaN
Monitor
Los diferentes sistemas operativos y lenguajes de programación pueden tener diferentes representaciones de cadena de NaN.
yayaYayaYaya%YAYANaNQNaNSqNaNsNaN1. # SNAN1. # QNAN-1. # IND+ nan.0
Dado que, en la práctica, los NaN codificados tienen un signo, un bit silencioso / de señalización y una 'información de diagnóstico' opcional (a veces llamada carga útil ), estos también se encontrarán a menudo en representaciones de cadena de NaN, por ejemplo:
-Yaya NaN12345-sNaN12300-NaN (s1234)
(existen otras variantes).
Codificación
En los formatos de almacenamiento de punto flotante que cumplen con el estándar IEEE 754 , los NaN se identifican mediante patrones de bits predefinidos específicos exclusivos de los NaN. El bit de signo no importa. Los NaN en formato binario se representan con el campo exponencial lleno de unos (como valores infinitos) y algún número distinto de cero en el campo significativo (para diferenciarlos de los valores infinitos). El estándar IEEE 754 original de 1985 ( IEEE 754-1985 ) solo describía formatos binarios de punto flotante y no especificaba cómo se etiquetaría el estado de señalización / silencio. En la práctica, el bit más significativo del campo significativo determina si un NaN es señalizador o silencioso. Como resultado, resultaron dos implementaciones diferentes, con significados inversos:
- la mayoría de los procesadores (incluidos los de la familia x86 de Intel y AMD , la familia Motorola 68000 , la familia AIM PowerPC , la familia ARM , la familia Sun SPARC y, opcionalmente, los nuevos procesadores MIPS ) establecen el bit de señalización / silencio en un valor distinto de cero si el NaN está en silencio, y a cero si el NaN está señalando. Por tanto, en estos procesadores, el bit representa una bandera;
is_quiet
- en los NaN generados por el PA-RISC y los procesadores MIPS antiguos, el bit de señalización / silencio es cero si el NaN está en silencio y distinto de cero si el NaN está señalizando. Por tanto, en estos procesadores, el bit representa una
is_signaling
bandera.
Se ha preferido la primera opción ya que permite que la implementación silencie un NaN de señalización simplemente estableciendo el bit de señalización / silencio en 1. Lo contrario no es posible con la última opción porque establecer el bit de señalización / silencio en 0 podría producir un infinito. [11]
La revisión de 2008 del estándar IEEE 754 ( IEEE 754-2008 ) hace recomendaciones formales para la codificación del estado de señalización / silencio.
- Para formatos binarios, el bit más significativo del campo significativo debería ser una
is_quiet
bandera. Es decir, este bit es distinto de cero si el NaN está en silencio y cero si el NaN está señalizando. - Para formatos decimales, ya sean codificados en binario o decimal, un NaN se identifica al tener los cinco bits superiores del campo de combinación después del bit de signo establecidos en unos. El sexto bit del campo es la
is_quiet
bandera. El estándar sigue la interpretación como unais_signaling
bandera. Es decir, el bit de señalización / silencio es cero si el NaN está en silencio y distinto de cero si el NaN está señalizando. Una señalización NaN se silencia al borrar este sexto bit.
Para la conformidad con IEEE 754-2008, el significado del bit de señalización / silencio en los procesadores MIPS recientes ahora se puede configurar a través del campo NAN2008 del registro FCSR. Este soporte es opcional en MIPS versión 3 y se requiere en la versión 5. [12]
El estado / valor de los bits restantes del campo significativo no está definido por el estándar. Este valor se denomina "carga útil" del NaN. Si una operación tiene una sola entrada de NaN y la propaga a la salida, el resultado de la carga útil de NaN debe ser la de la entrada NaN (esto no siempre es posible para los formatos binarios cuando el estado de señalización / silencio está codificado por una is_signaling
bandera, como se explicó anteriormente ). Si hay varias entradas de NaN, el resultado de la carga útil de NaN debe ser de uno de los NaN de entrada; la norma no especifica cuál.
Referencias
- ↑ a b Bowman, Kenneth (2006). Introducción a la programación con IDL: lenguaje de datos interactivo . Prensa académica. pag. 26 . ISBN 978-0-12-088559-6.
- ^ Prensa, William H .; Teukolsky, Saul A .; Vetterling, William T .; Flannery, Brian P. (2007). Recetas numéricas: el arte de la informática científica . Prensa de la Universidad de Cambridge. pag. 34 . ISBN 978-0-521-88068-8.
- ^ William Kahan (1 de octubre de 1997). "Notas de la conferencia sobre el estado del estándar IEEE 754 para aritmética de coma flotante binaria" (PDF) .
- ^ David HC Chen (21 de febrero de 2017). "La eliminación / degradación de las operaciones MinNum y MaxNum de IEEE 754 ™ -2018" (PDF) . Consultado el 6 de mayo de 2019 .
- ^ "754R Minutos" . 19 de mayo de 2017 . Consultado el 25 de junio de 2017 .
- ^ David Goldberg. "Lo que todo informático debe saber sobre el punto flotante" .
- ^ "Manual del desarrollador de software de arquitecturas Intel 64 e IA-32 Volumen 1: Arquitectura básica" . Abril de 2008. págs. 118-125, 266-267, 334-335.
- ^ "Justificación de la norma internacional — lenguajes de programación — C, revisión 5.10" (PDF) . Abril de 2003. p. 180.
- ^ "ArithmeticException (Java Platform SE 8)" . docs.oracle.com .
- ^ " Matemáticas :: BigInt " . perldoc.perl.org . Consultado el 12 de junio de 2015 .
- ^ "Re: (largos) sNaNs no son lo que podrían ser ..." grouper.ieee.org . 15 de octubre de 2010 . Consultado el 5 de noviembre de 2020 .
- ^ "Arquitectura MIPS® para programadores - Volumen IA: Introducción a la arquitectura MIPS64®" (PDF) . MIPS Technologies, Inc. 20 de noviembre de 2013. p. 79 . Consultado el 27 de septiembre de 2017 .
enlaces externos
- No es un número , foldoc.org
- Estándar IEEE 754-2008 para aritmética de punto flotante (se requiere suscripción)