java floating-point strictfp

¿Cuándo debo usar la palabra clave “strictfp” en java?



transient java (8)

Busqué lo que esto hace, pero ¿alguien realmente tiene un ejemplo de cuándo strictfp palabra clave strictfp en Java? ¿Alguien realmente ha encontrado un uso para esto?

¿Habría efectos secundarios de solo ponerlo en todas mis operaciones de punto flotante?


A continuación, el ejemplo puede ayudar a comprender esto con mayor claridad: en java siempre que estemos utilizando la búsqueda de información precisa para cualquier operación, por ejemplo, si hacemos doble num1 = 10e + 102; doble num2 = 8e + 10; resultado = num1 + num2;

The output will be so long and not precise, becasue it is precissed by the hardware e.g JVM and JIT has the license as long as we dont have specify it Strictfp Marking it Strictfp will make the result Uniform on every hardware and platform, because its precised value will be same One scenario I can see is in a distributed application (or multiplayer game) where all floating-point calculations need to be deterministic no matter what the underlying hardware or CPU is.


Aquí hay varias referencias:

  • Utilizando strictfp (Consejo técnico de JDC)
  • jGuru: ¿ Para qué es el modificador strictfp? ¿Cuándo consideraría usarlo?

    Básicamente, todo se reduce a si le importa o no que los resultados de las expresiones de punto flotante en su código sean rápidos o predecibles. Por ejemplo, si necesita las respuestas de su código que utilizan valores de punto flotante para ser consistentes en múltiples plataformas, entonces utilice strictfp .

  • strictfp - Java Glossary

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

  • Y finalmente, la especificación real del lenguaje Java, §15.4 Expresiones estrictas de FP :

    Dentro de una expresión estricta de FP, todos los valores intermedios deben ser elementos del conjunto de valores flotantes o el conjunto de valores dobles, lo que implica que los resultados de todas las expresiones estrictas de FP deben ser los pronosticados por la aritmética IEEE 754 en operandos representados utilizando formatos simples y dobles . Dentro de una expresión que no es FP-estricta, se otorga cierto margen de maniobra para que una implementación utilice un rango de exponente extendido para representar resultados intermedios; En términos generales, el efecto neto es que un cálculo puede producir "la respuesta correcta" en situaciones en las que el uso exclusivo del conjunto de valores flotantes o el conjunto de valores dobles puede provocar desbordamiento o desbordamiento.

Sin embargo, nunca he tenido un uso personal para ello.


Como se mencionó en las otras respuestas, los resultados del punto flotante intermedio se ajustan a 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 complica cuando el JIT optimiza un cálculo particular; el orden en que las instrucciones podrían ser diferentes cada vez resultando en un redondeo ligeramente diferente.

La sobrecarga en la que incurre el strictfp es probable que sea muy dependiente del procesador y JIT. Este artículo de wikipedia sobre SSE2 parece tener alguna idea del problema. Por lo tanto, si el JIT puede generar instrucciones 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 en el que los rayos cósmicos potenciales deben eliminarse de los valores de píxeles. Si algún investigador externo tiene el mismo valor de píxel y el rayo cósmico frente a ellos, debería obtener el mismo valor resultante que nuestro software.


Strictfp garantiza que obtenga exactamente los mismos resultados de sus cálculos de punto flotante en cada plataforma. Si no usa strictfp, la implementación de JVM es libre de usar precisión adicional cuando esté disponible.

Desde el JLS :

Dentro de una expresión estricta de FP, todos los valores intermedios deben ser elementos del conjunto de valores flotantes o el conjunto de valores dobles, lo que implica que los resultados de todas las expresiones estrictas de FP deben ser los pronosticados por la aritmética IEEE 754 en operandos representados utilizando formatos simples y dobles . Dentro de una expresión que no es FP-estricta, se otorga cierto margen de maniobra para que una implementación utilice un rango de exponente extendido para representar resultados intermedios; En términos generales, el efecto neto es que un cálculo puede producir "la respuesta correcta" en situaciones en las que el uso exclusivo del conjunto de valores flotantes o el conjunto de valores dobles puede provocar desbordamiento o desbordamiento.

En otras palabras, se trata de asegurarse de que Write-Once-Run-Anywhere en realidad significa Write-Once-Get-Equally-Wrong-Results-Everywhere .

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


Todo comenzó con una historia,

Cuando Java estaba siendo desarrollado por James Gosling, Herbert y el resto de su equipo. Tenían en mente esta locura llamada independencia de plataforma . Querían hacer Oak (Java) mucho mejor que funcionaría exactamente igual en cualquier máquina con diferentes conjuntos de instrucciones, incluso ejecutando diferentes sistemas operativos. Pero hubo un problema con los números de punto decimal también conocidos como punto flotante y doble en los lenguajes de programación. Algunas máquinas fueron construidas apuntando a la eficiencia, mientras que el resto apuntaba a la precisión Por lo tanto, 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 estaba en contra de la idea central de construir un lenguaje de plataforma independiente. Además, esto podría llevar a la pérdida de precisión / datos cuando un código se construye en una máquina (tiene el doble de tamaño de 64 bits) y se ejecuta en otro tipo de máquina (tiene el doble de tamaño de 80 bits).

El aumento de tamaño se puede tolerar, pero el tamaño reducido no se puede tolerar. Entonces, se encontraron con un concepto de punto estricto, es decir, punto flotante estricto . Si usa esta palabra clave con una clase / función, entonces su punto flotante y sus dobles tienen un tamaño consistente sobre cualquier máquina. es decir, 32/64 -bit respectivamente.


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

Leyendo entre líneas, la implicación es que si no especifica strictfp , entonces el compilador JVM y JIT tienen licencia para calcular sus cálculos de punto flotante como lo deseen. En aras de la velocidad, lo más probable es que deleguen el cálculo en su procesador. Con un strictfp , 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é querrías usar strictfp ? Un escenario que puedo ver es en una aplicación distribuida (o juego de varios jugadores) donde todos los cálculos de punto flotante deben ser deterministas sin importar cuál sea el hardware o la CPU subyacente. ¿Qué es la compensación? Tiempo de ejecución más probable.


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

Sin ese modificador, los puntos flotantes utilizados en los métodos podrían 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 ejecuta la JVM. El inconveniente 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 en una base de método por método, declarando un método como strictfp .

~ SCJP Sun® Programador certificado para Java ™ 6 - Kathy Sierra & Bert Bates ~


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

  • Esto se puede usar en toda la clase como "public strictfp class StrictFpModifierExample {}" o en el método "public strictfp void example ()". Si se usa en la clase, todos los métodos seguirán IEEE 754 y si se usa en el método, entonces el método particular siga IEEE 754.

  • ¿Por qué se utiliza ?? ::: Como las diferentes plataformas tienen un hardware de punto flotante diferente que calcula con mayor precisión y mayor rango de valores que lo que requiere la especificación de Java, que puede producir una salida diferente en diferentes formas de placa. Por lo tanto, confirma la misma salida independientemente de la diferencia. formas de placa

  • strictfp también garantiza aprovechar la velocidad y la precisión de las operaciones de punto flotante de precisión extendida.

  • No hay desventaja con esta palabra clave que podemos usar cuando estamos haciendo cálculos de punto flotante

  • Mi último punto es: ¿Qué es IEEE754 en resumen? IEEE 754 define el método estándar tanto para los cálculos de punto flotante como para el almacenamiento de valores de punto flotante en uno solo (32 bits, usado en flotadores Java) o doble (64 bits, usado en Java se dobla) precisión. También define normas para cálculos intermedios y para formatos de precisión extendida.