¿Tiene números de punto flotante de 64 bits comportan de forma idéntica en todos los ordenadores modernos?

StackOverflow https://stackoverflow.com/questions/2149900

Pregunta

Me gustaría saber si puedo asumir que las mismas operaciones en mismos números de punto flotante de 64 bits da exactamente los mismos resultados en cualquier PC moderno y en la mayoría de los lenguajes de programación comunes? (C ++, Java, C #, etc.). Podemos suponer, que estamos operando en números y el resultado es también un número (no hay NaNs, INF y así sucesivamente).

Yo sé que hay dos normas muy mismo tipo de cálculo utilizando números de punto flotante (IEEE 854 a 1987 e IEEE 754-2008). Sin embargo no sé cómo es en la práctica.

¿Fue útil?

Solución

Los procesadores modernos que implementan de 64 bits en coma flotante suele poner en práctica algo que está cerca del estándar IEEE 754-1985, recientemente sustituida por la norma 754-2008.

Los 754 lo previsto por la norma resultado que se debe obtener a partir de ciertas operaciones básicas, sobre todo suma, resta, multiplicación, división, raíz cuadrada, y la negación. En la mayoría de los casos, el resultado numérico se especifica con precisión: El resultado debe ser el número representable que está más cerca del resultado matemático exacto en la dirección especificada por el modo de redondeo (para más cercana, hacia el infinito, hacia cero, o hacia el infinito negativo). En "al más cercano" modo, los estándares también especifica cómo los empates.

Debido a esto, las operaciones que no implican condiciones de excepción tales como desbordamiento obtendrá los mismos resultados en diferentes procesadores que cumplen con el estándar.

Sin embargo, hay varios problemas que interfieren con la obtención de resultados idénticos en diferentes procesadores. Uno de ellos es que el compilador es a menudo libre de implementar secuencias de operaciones de punto flotante en una variedad de maneras. Por ejemplo, si se escribe "a = b c + d" en C, donde todas las variables se declaran doble, el compilador es libre para computar "b c", ya sea en la aritmética de doble precisión o algo con más de alcance o de precisión. Si, por ejemplo, el procesador tiene registros capaces de contener precisión extendida números de punto flotante y hacer aritmética con precisión extendida no toma más tiempo de CPU que hacer aritmética con doble precisión, un compilador puede generar código usando extendida -precisión. En el procesador tal, que no podría obtener los mismos resultados que lo haría en otro procesador. Incluso si el compilador hace esto regularmente, puede que no en algunas circunstancias debido a que los registros están llenos durante una secuencia complicada, por lo que almacena los resultados intermedios en la memoria temporal. Cuando se hace eso, se podría escribir sólo el doble de 64 bits en lugar del número extendida precisión. Así que una rutina que contiene aritmética de punto flotante puede dar resultados diferentes sólo porque se compiló con código diferente, tal vez inline en un solo lugar, y el compilador necesita registros para otra cosa.

Algunos procesadores tienen instrucciones para calcular una multiplicación y una adición en una instrucción, por lo que "b c + d" puede ser calculada sin ninguna aproximación intermedia y obtener un resultado más preciso que en un procesador que calcula en primer lugar b C y luego se agrega d.

Su compilador podría tener interruptores de control en el comportamiento como éste.

Hay algunos lugares donde el estándar 754-1985 no requiere un resultado único. Por ejemplo, al determinar si se ha producido flujo inferior (un resultado es demasiado pequeño para ser representados con precisión), el estándar permite una implementación para hacer la determinación, ya sea antes o después de que redondea la mantisa (los bits de fracción) a la precisión de destino. Por lo que algunas implementaciones le dirá desbordamiento ha ocurrido cuando otras implementaciones no.

Una característica común de los procesadores es tener un modo "casi IEEE 754" que elimina la dificultad de tratar con desbordamiento mediante la sustitución de cero en lugar de devolver el número muy pequeño que la norma exige. Naturalmente, obtendrá un número diferente cuando se ejecuta en un modo tal que cuando se ejecuta en el modo más compatible. El modo no puede ser compatible con el conjunto predeterminado por su compilador y / o sistema operativo, por razones de rendimiento.

Tenga en cuenta que una implementación IEEE 754 es típicamente no proporcionada por el hardware, sino simplemente por una combinación de hardware y software. El procesador puede hacer la mayor parte del trabajo sino que se basan en el software para manejar ciertas excepciones, juego de ciertos modos, y así sucesivamente.

Cuando se mueve más allá de las operaciones aritméticas básicas a cosas como el seno y el coseno, que son muy dependientes de la biblioteca que utiliza. funciones trascendentales unare generalmente calculada con aproximaciones coordinada cuidadosamente. Las implementaciones se han desarrollado de forma independiente por varios ingenieros y obtener resultados diferentes unos de otros. En un sistema, la función de pecado puede dar resultados precisos dentro de un ULP (unidad de menos precisión) para argumentos pequeño (menos de pi o menos), pero más grandes errores para grandes argumentos. En otro sistema, la función de pecado pudiera dar resultados exactos dentro de varios ULP para todos los argumentos. No biblioteca matemática actual es conocida por producir resultados correctamente redondeados para todas las entradas. Hay un proyecto, crlibm (correctamente redondeado libm), que ha realizado un trabajo bien para con este objetivo, y tienen implementaciones desarrollados para una parte significativa de la biblioteca matemática que son correctamente redondeada y tienen un buen rendimiento, pero no toda la biblioteca matemática sin embargo.

En resumen, si usted tiene un conjunto manejable de cálculos, entender su aplicación compilador, y son muy cuidadosos, puede confiar en los resultados idénticos en diferentes procesadores. De lo contrario, conseguir resultados completamente idénticos no es algo que se puede confiar.

Otros consejos

Si se refiere a conseguir exactamente el mismo resultado, entonces la respuesta es no.

Incluso podría obtener resultados diferentes para depuración (no optimizado) construye la liberación vs construye (optimizado) en la misma máquina, en algunos casos, así que ni siquiera asumen que los resultados podrían ser siempre idénticos en diferentes máquinas.

(Esto puede ocurrir por ejemplo en un ordenador con un procesador Intel, si el optimizador mantiene una variable para un resultado intermedio en un registro, que se almacena en la memoria en la construcción sin optimizar. Desde registros Intel FPU son 80 bits, y el doble variables son 64 bits, el resultado intermedio se almacenarán con mayor precisión en la construcción optimizada, causando valores diferentes en los resultados posteriores.).

En la práctica, sin embargo, a menudo se puede obtener los mismos resultados, pero no se debe confiar en ella.

Moderno FPU toda implementar IEEE754 flotadores en formatos individuales y dobles, y algunos en formato extendido. Un cierto conjunto de operaciones están soportadas (casi cualquier cosa en math.h), con algunas instrucciones especiales flotando por ahí.

suponiendo que usted está hablando de la aplicación de múltiples operaciones, no creo que obtendrá el número exacto. arquitectura de la CPU, el uso del compilador, los ajustes de optimización cambiará los resultados de sus cálculos.

si usted quiere decir el orden exacto de las operaciones (en el plano de montaje), creo que seguirá recibiendo los chips de Intel utilizan ejemplo variations.for precisión extendida (80 bits) internamente, lo cual puede no ser el caso para otras CPU. (No creo que la precisión extendida es obligatoria)

El mismo programa C # pueden llevar a cabo diferentes resultados numéricos en el mismo PC, una vez compilado en modo de depuración sin optimización, por segunda vez compilado en modo de lanzamiento con la optimización activada. Esa es mi experiencia personal. Nosotros no consideramos esto cuando hemos creado un conjunto de pruebas de regresión automática para uno de nuestros programas, por primera vez, y estaban completamente sorprendidos de que una gran cantidad de nuestras pruebas no sin razón aparente.

Para C # en x86, se utilizan registros de PF 80 bits.

El C # estándar dice que el procesador debe funcionar a la misma precisión que, o mayor que, el tipo en sí (es decir, 64 bits en el caso de un 'doble'). Promociones están permitidos, excepto para el almacenamiento. Eso significa que los locales y parámetros podrían estar en mayor que la precisión de 64 bits.

En otras palabras, la asignación de una variable miembro a una variable local podría (y de hecho la voluntad bajo ciertas circunstancias) sea suficiente para dar una desigualdad.

Ver también: / doble precisión en la depuración / liberación modos

Para el tipo de datos de 64 bits, sólo que sé de "doble precisión" / "binary64" de la IEEE 754 (1985 y 2008 no difieren mucho aquí para los casos comunes) que se utiliza.

Nota:. Los tipos radix definidos en la norma IEEE 854-1987 son reemplazadas por IEEE 754-2008 de todos modos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top