2009-02-05 15 views
221

He buscado lo que hace esto, pero ¿alguien realmente tiene un ejemplo de cuándo usaría la palabra clave strictfp en Java? ¿Alguien ha encontrado un uso para esto?¿Cuándo debería usar la palabra clave "strictfp" en java?

¿Habría algún efecto secundario de solo ponerlo en todas mis operaciones de punto flotante?

+0

Siempre, a menos que realmente necesite el rendimiento más de lo que necesita reproducibilidad. – Antimony

+0

@Antimonio - o la precisión/corrección. x86/x64, por ejemplo, usa registros de coma flotante de 80 bits internamente, por lo que el resultado será más preciso para un cálculo largo sin strictfp. –

+0

@Robert En realidad, la especificación garantiza la precisión limitada de la mantisa. La única diferencia es que puede usar una precisión de exponente mayor que la normal, que tiene diferencias en casos excepcionales debido al doble redondeo. – Antimony

Respuesta

226

Strictfp le asegura que obtendrá exactamente los mismos resultados de sus cálculos de coma flotante en cada plataforma. Si no usa strictfp, la implementación de JVM es libre de usar precisión adicional donde esté disponible.

From the JLS:

Dentro de una expresión FP-estricta, todos valores intermedios deben ser elementos del valor flotante SET o el doble juego valor, lo que implica que los resultados de todas las expresiones FP-estrictas debe ser los predichos por aritmética IEEE 754 en operandos representados utilizando único y formatos dobles. Dentro de una expresión que no es FP-strict, se concede un margen de acción de para una implementación de para usar un rango de exponente extendido para representar resultados intermedios; el efecto neto, en términos generales, es que un cálculo podría producir "la correcta respuesta" en situaciones en exclusiva uso del conjunto de valor flotante o doble juego valor podría resultar en desbordamiento o subdesbordamiento .

En otras palabras, se trata de asegurarse de que escritura única de ejecución en cualquier lugar significa en realidad Write-Once-Get-igualmente erróneos en los resultados en todas partes.

Con strictfp sus resultados son portátiles, sin ellos es más probable que sean precisos.

+21

Utilícelo para obtener resultados científicos reproducibles y pruebas de unidad de bits exactos. –

+60

Write-Once-Get-Equally-Wrong-Results-Everywhere: D – vach

+0

"Si no usa strictfp, la implementación de JVM es libre de usar una precisión adicional donde esté disponible": hace que suene como algo malo: P –

57

Wikipedia en realidad tiene un buen artículo sobre este tema here, con un enlace a la especificación de Java.

Al leer entre líneas, la implicación es que si no especifica strictfp, entonces el compilador JVM y JIT tiene licencia para calcular sus cálculos de coma flotante como lo desee. En aras de la velocidad, lo más probable es que deleguen el cálculo en su procesador. Con strictfp activado, los cálculos deben cumplir con los estándares aritméticos IEEE 754, lo que, en la práctica, probablemente signifique que la JVM realizará el cálculo.

Entonces, ¿por qué quieres usar strictfp? Un escenario que puedo ver es en una aplicación distribuida (o juego multijugador) donde todos los cálculos de coma flotante deben ser deterministas sin importar cuál sea el hardware o CPU subyacente. ¿Cuál es la compensación? Probablemente el tiempo de ejecución.

+4

"un rango de exponente extendido para representar resultados intermedios" no es "licencia para calcular los cálculos de coma flotante como quieran", y en la práctica, incluso los cálculos 'strictfp' hacen uso incluso de una FPU 8087 poco útil. Es solo el caso que se requiere un poco de cuidado entonces. Consulte http://stackoverflow.com/questions/18496560/how-do-java-runtimes-targeting-pre-sse2-processors-implement-floating-point-basi –

17

Aquí hay varias referencias:

  • Using strictfp (JDC Tech Tip)
  • jGuru: What is the strictfp modifier for? When would I consider using it?

    Básicamente, lo que todo se reduce a si está o no les importa que la los resultados de las expresiones de coma flotante en su código son rápidos o predecibles. Por ejemplo, si necesita las respuestas de su código que usa valores de punto flotante para ser coherente en múltiples plataformas, utilice strictfp.

  • strictfp - Java Glossary

    hardware de punto flotante calcula con mayor precisión, y con un mayor rango de valores de la especificación Java requiere. Sería confuso si algunas plataformas proporcionaran más precisión que otras. Cuando utiliza el modificador strictfp en un método o clase, el compilador genera código que cumple estrictamente las especificaciones de Java para resultados idénticos en todas las plataformas. Sin strictfp, es ligeramente más laxo, pero no tan floja como para usar los pedacitos de guarda en el Pentium para dar 80 bits de precisión.

  • Y finalmente el actual especificación del lenguaje Java, §15.4 FP-strict Expressions:

    Dentro de una expresión FP-estricta, todos los valores intermedios deben ser elementos del valor flotante establecer o el conjunto de doble valor, lo que implica que la los resultados de todas las expresiones FP-strict deben ser los predichos por la aritmética IEEE 754 en los operandos representados utilizando formatos simples y dobles. Dentro de una expresión que no es FP-estricta, se concede un margen para que una implementación use un rango de exponente extendido para representar resultados intermedios; el efecto neto, en términos generales, es que un cálculo puede producir "la respuesta correcta" en situaciones donde el uso exclusivo del conjunto de valores de flotación o el conjunto de valores dobles puede dar lugar a un desbordamiento o desbordamiento.

nunca he tenido personalmente un uso para él, sin embargo.

12

Como las otras respuestas mencionadas lo hacen los resultados del punto flotante intermedio para cumplir con la especificación IEEE. En particular, los procesadores x86 pueden almacenar resultados intermedios con diferente precisión de la especificación IEEE. La situación se vuelve más complicada cuando el JIT optimiza un cálculo particular; el orden en que las instrucciones pueden ser diferentes cada vez resulta en un redondeo ligeramente diferente.

La sobrecarga incurrida por strictfp probablemente sea muy dependiente del procesador y JIT. Este artículo de la wikipedia en SSE2 parece tener alguna idea del problema. Entonces, si el JIT puede generar instrucciones de SSE para realizar un cálculo, parece que strictfp no tendrá ninguna sobrecarga.

En mi proyecto actual, hay algunos lugares donde utilizo strictfp. Hay un punto donde los rayos cósmicos potenciales deben ser eliminados de los valores de píxel. Si algún investigador externo tiene el mismo valor de píxel y el mismo rayo cósmico, deben obtener el mismo valor resultante que nuestro software.

8
  • strictfp es un modificador que restringe cálculos de punto flotante según IEEE 754.

  • Esto se puede utilizar en toda la clase como "strictfp público StrictFpModifierExample clase {}" o en el método de "strictfp pública ejemplo void() ". Si se usa en clase, todos los métodos seguirán IEEE 754 y si se usa en el método, el método particular seguirá a IEEE 754.

  • Por qué se usa ??: Como diferentes plataformas tienen diferentes hardware de punto flotante que calcula con más precisión y mayor ter rango de valores que la especificación java requiere que pueda producir una salida diferente en diferentes formas de placa. Así que confirma la misma salida independientemente de las diferentes placas

  • strictfp también garantiza el aprovechamiento de la velocidad y precisión de la precisión extendida flotante operaciones puntuales.

  • No hay ninguna desventaja con esta palabra clave se puede utilizar cuando estamos haciendo cálculos de punto flotante

  • Mi último punto es --¿Qué es IEEE754 en definitiva IEEE 754 define un método estándar para los cálculos de punto flotante y almacenamiento de valores de coma flotante en precisión simple (32 bits, utilizada en flotantes Java) o doble (64 bits, utilizada en Java dobles). También define normas para cálculos intermedios y para formatos de precisión ampliados.

2

strictfp es una palabra clave y se pueden usar como un modificador no no el acceso para las clases o unos métodos (pero nunca variables). Marcar una clase como strictfp significa que cualquier código de método en la clase se ajustará a las reglas estándar IEEE 754 para los puntos flotantes.

Sin ese modificador, los puntos flotantes utilizados en los métodos pueden comportarse de una manera dependiente de la plataforma. Con él puede predecir cómo se comportarán sus puntos flotantes independientemente de la plataforma subyacente en la que se esté ejecutando la JVM. La desventaja es que si la plataforma subyacente es capaz de soportar una mayor precisión, un método strictfp no podrá aprovecharla.

Si no declara una clase como strictfp, aún puede obtener el comportamiento strictfp método por método, declarando un método como strictfp.

~ SCJP Sun®Certified programador para Java ™ 6 - Kathy Sierra & Bert Bates ~

15

Todo comenzó con una historia,

Cuando java estaba siendo desarrollado por James Gosling, Herbert y resto de su equipo. Tenían esta cosa loca en mente llamada independiente de la plataforma. Querían hacer oak (Java) tanto mejor que funcionaría exactamente igual en cualquier máquina que tenga un conjunto de instrucciones diferente, incluso ejecutando diferentes sistemas operativos. Pero, hubo un problema con los números de punto decimal también conocido como punto flotante y doble en los lenguajes de programación. Algunas máquinas se construyeron teniendo como objetivo la eficiencia mientras que el resto se enfocaba en la precisión. Entonces, las máquinas posteriores (más precisas) tenían un tamaño de punto flotante de 80 bits, mientras que las máquinas anteriores (más eficientes/más rápidas) tenían dobles de 64 bits. Pero, esto fue en contra de la idea central de construir un lenguaje independiente de plataforma.Además, esto puede conducir a la pérdida de precisión/datos cuando se crea un código en una máquina (que tiene el doble del tamaño de 64 bits) y se ejecuta en otro tipo de máquina (que tiene el doble de tamaño de 80 bits).

Se puede tolerar el cambio de tamaño, pero no se puede reducir el tamaño. Entonces, encontraron un concepto de strictfp, es decir, estricto punto flotante. Si usa esta palabra clave con una clase/función, su coma flotante y sus dobles tienen un tamaño constante en cualquier máquina. es decir, 32/64 bits, respectivamente.

+1

strictfp se introdujo en Java 1.2. Esto fue mucho más tarde que cuando se diseñó el roble. –

Cuestiones relacionadas