Quando devo usar a palavra-chave "strictfp" em java?


258

Eu procurei o que isso faz, mas alguém realmente tem um exemplo de quando você usaria a strictfppalavra - chave em Java? Alguém realmente encontrou um uso para isso?

Haveria efeitos colaterais de colocá-lo em todas as minhas operações de ponto flutuante?


1
Sempre, a menos que você realmente precise do desempenho mais do que da reprodutibilidade.
Antimony

1
@Antimony - ou a precisão / correção. x86 / x64, por exemplo, usa registros de ponto flutuante de 80 bits internamente, para que o resultado seja mais preciso para um cálculo longo sem strictfp.
31416 Robert

1
@Robert Na verdade, as especificações garantem precisão limitada da mantissa. A única diferença é que ele pode usar uma precisão de expoente maior que o normal, o que apresenta diferenças em casos raros devido ao arredondamento duplo.
Antimony

Estou pensando que, além da opção de espalhar esse modificador útil por toda a junta, novos tipos de dados sfloat e sdouble primitive strictfp podem ser uma boa idéia.
TheRiley

Respostas:


274

O Strictfp garante que você obtenha exatamente os mesmos resultados de seus cálculos de ponto flutuante em todas as plataformas. Se você não usar o strictfp, a implementação da JVM será livre para usar precisão extra quando disponível.

Do JLS :

Dentro de uma expressão estrita de FP, todos os valores intermediários devem ser elementos do conjunto de valores flutuantes ou do conjunto de valores duplos, implicando que os resultados de todas as expressões estritas de FP devem ser aqueles previstos pela aritmética IEEE 754 em operandos representados usando formatos simples e duplos . Dentro de uma expressão que não é estrita ao FP, é concedida alguma margem de manobra para uma implementação usar um intervalo de expoente estendido para representar resultados intermediários; o efeito líquido, grosso modo, é que um cálculo pode produzir "a resposta correta" em situações em que o uso exclusivo do conjunto de valores flutuantes ou do conjunto de valores duplos pode resultar em estouro ou estouro.

Em outras palavras, trata-se de garantir que Write-Once-Run-Anywhere realmente signifique Write-Once-Get-Equally-Wrong-Results-Everywhere .

Com strictfp, seus resultados são portáteis; sem ele, é mais provável que sejam precisos.


28
Use-o para resultados científicos reproduzíveis e testes de unidade de bits exatos.
Aleksandr Dubinsky

1
"Se você não usa o strictfp, a implementação da JVM é livre para usar precisão extra quando disponível" - você faz isso parecer ruim: P
AMDG

@LinkTheProgrammer certamente pode ser uma coisa ruim
Tim

@TimCastelijns Suponho que Happy Wheels seja sua referência? As repetições registram pressionamentos de tecla; devido à diversidade de precisão da implementação do FP-math, os replays são precisos apenas em hardware semelhante. Você pode citar um problema mais realista causado pela variabilidade matemática do ponto flutuante? Posso imaginar talvez um simulador de partículas, mas o que mais?
AMDG 26/03

Então isso significa que devemos sempre usar o strictfp na produção, onde várias plataformas estão envolvidas?
22819 Beatrice

65

A Wikipedia realmente tem um bom artigo sobre esse tópico aqui , com um link para a especificação Java.

Lendo nas entrelinhas, a implicação é que, se você não especificar strictfp, o compilador JVM e JIT terá licença para calcular seus cálculos de ponto flutuante da maneira que desejar. No interesse da velocidade, eles provavelmente delegarão a computação no seu processador. Com strictfpativado, os cálculos devem estar em conformidade com os padrões aritméticos IEEE 754, o que, na prática, provavelmente significa que a JVM fará o cálculo.

Então, por que você gostaria de usar strictfp? Um cenário que posso ver é em um aplicativo distribuído (ou jogo multiplayer) em que todos os cálculos de ponto flutuante precisam ser determinísticos, independentemente do hardware ou da CPU subjacente. Qual é o compromisso? Tempo de execução provavelmente.


5
“Um intervalo extenso de expoentes para representar resultados intermediários” não é “licença para calcular seus cálculos de ponto flutuante da maneira que eles desejarem” e, na prática, até mesmo os strictfpcálculos usam até uma FPU 8087 inútil. É apenas o caso em que é necessário um pouco de cuidado. Veja stackoverflow.com/questions/18496560/…
Pascal Cuoq

Concordo com a @PascalCuoq re: "licença para calcular seus cálculos de ponto flutuante da maneira que eles desejarem" . De qualquer forma, o oposto parece verdadeiro neste caso, pois strictfpgarante a conformidade com o padrão IEEE 754 (para que você obtenha o mesmo resultado em todas as plataformas). A única desvantagem que vejo é que você pode perder os benefícios de ter uma FPU realmente boa disponível em seu hardware nativo.
TypeRacer

25

Tudo começou com uma história,

Quando o java estava sendo desenvolvido por James Gosling, Herbert e o restante de sua equipe. Eles tinham essa coisa louca em mente chamada independência de plataforma . Eles queriam fazer carvalho (Java)muito melhor que funcionaria exatamente da mesma maneira em qualquer máquina com um conjunto de instruções diferente, mesmo executando sistemas operacionais diferentes. Porém, houve um problema com os números decimais, também conhecidos como ponto flutuante e o dobro nas linguagens de programação. Algumas máquinas foram construídas visando a eficiência, enquanto o resto estava buscando a precisão. Portanto, as máquinas posteriores (mais precisas) tinham tamanho de ponto flutuante de 80 bits, enquanto as máquinas anteriores (mais eficientes / rápidas) tinham 64 bits duplos. Mas isso foi contra a ideia central de criar uma linguagem independente de plataforma. Além disso, isso pode levar à perda de precisão / dados quando um código é criado em alguma máquina (com o dobro do tamanho de 64 bits) e executado em outro tipo de máquina (com o dobro do tamanho de 80 bits).

O dimensionamento para cima pode ser tolerado, mas o tamanho para baixo não pode ser. Então, eles se depararam com um conceito de strictfp, isto é, ponto flutuante estrito . Se você usar essa palavra-chave com uma classe / função, seu ponto flutuante e seu dobro terão um tamanho consistente sobre qualquer máquina. ou seja, 32/64 bits, respectivamente.


8
strictfp foi introduzido no Java 1.2. Isso foi muito mais tarde do que quando o carvalho foi projetado.
Thorbjørn Ravn Andersen

"números de ponto decimal também conhecido como ponto flutuante" - decimal significa base 10 e não tem nada a ver com representações de ponto flutuante.
aioobe

21

Aqui estão várias referências:

  • Usando strictfp (Dica técnica do JDC)
  • jGuru: Para que serve o modificador strictfp ? Quando eu consideraria usá-lo?

    Basicamente, tudo se resume a saber se você se importa ou não com o fato de os resultados das expressões de ponto flutuante no seu código serem rápidos ou previsíveis. Por exemplo, se você precisar das respostas fornecidas pelo seu código que usam valores de ponto flutuante para serem consistentes em várias plataformas, use-o strictfp.

  • strictfp - Glossário Java

    O hardware de ponto flutuante calcula com mais precisão e com uma faixa de valores maior do que a especificação Java requer. Seria confuso se algumas plataformas dessem mais precisão do que outras. Quando você usa o strictfpmodificador em um método ou classe, o compilador gera código que segue estritamente as especificações Java para resultados idênticos em todas as plataformas. Sem strictfp, é um pouco mais relaxado, mas não tão relaxado a ponto de usar os bits de proteção no Pentium para fornecer 80 bits de precisão.

  • E, finalmente, a Especificação de Linguagem Java real, §15.4 Expressões estritas de FP :

    Dentro de uma expressão estrita de FP, todos os valores intermediários devem ser elementos do conjunto de valores flutuantes ou de valor duplo, o que implica que os resultados de todas as expressões estritas de FP devem ser aqueles previstos pela aritmética IEEE 754 em operandos representados usando formatos simples e duplos . Dentro de uma expressão que não é estrita ao FP, é concedida alguma margem de manobra para uma implementação usar um intervalo de expoente estendido para representar resultados intermediários; o efeito líquido, grosso modo, é que um cálculo pode produzir "a resposta correta" em situações em que o uso exclusivo do conjunto de valores flutuantes ou do conjunto de valores duplos pode resultar em estouro ou estouro.

Eu nunca tive um uso pessoal para isso, no entanto.


12

Como as outras respostas mencionadas, os resultados do ponto flutuante intermediário estão em conformidade com a especificação IEEE. Em particular, os processadores x86 podem armazenar resultados intermediários com precisão diferente da especificação IEEE. A situação fica mais complicada quando o JIT otimiza uma computação específica; a ordem em que as instruções podem ser diferentes a cada vez, resultando em arredondamentos ligeiramente diferentes.

A sobrecarga incorrida pelo strictfp provavelmente será muito dependente do processador e do JIT. Este artigo da wikipedia sobre SSE2 parece ter algumas dicas sobre o problema. Portanto, se o JIT puder gerar instruções SSE para executar um cálculo, parece que strictfp não terá nenhuma sobrecarga.

No meu projeto atual, existem alguns lugares onde eu uso strictfp. Há um ponto em que os raios cósmicos em potencial precisam ser removidos dos valores de pixel. Se algum pesquisador externo tiver o mesmo valor de pixel e raio cósmico à frente deles, deverá obter o mesmo valor resultante do nosso software.


8
  • strictfp é um modificador que restringe os cálculos de ponto flutuante conforme IEEE 754.

  • Isso pode ser usado em toda a classe, como "public strictfp class StrictFpModifierExample {}" ou no método "public strictfp void example ()". Se for usado na classe, todos os métodos seguirão o IEEE 754 e, se usado no método, o método específico será siga a IEEE 754.

  • Por que é usado ?? ::: Como plataformas diferentes possuem hardware de ponto flutuante diferente, que calcula com mais precisão e maior faixa de valores do que a especificação java exige, o que pode produzir uma saída diferente em diferentes formas de placa. Assim, confirma a mesma saída independentemente da diferença placas

  • strictfp também garante tirar proveito da velocidade e precisão das operações de ponto flutuante de precisão estendida.

  • Não há desvantagem com essa palavra-chave que podemos usar quando estamos fazendo cálculos de ponto flutuante

  • Meu último argumento é --O que é o IEEE754 em resumo? O IEEE 754 define o método padrão para cálculos de ponto flutuante e armazenamento de valores de ponto flutuante em simples (32 bits, usado em Java floats) ou duplo (64 bits, usado em Java) dobra) precisão.Também define normas para cálculos intermediários e para formatos de precisão estendidos.


2

strictfpé uma palavra-chave e pode ser usada como um modificador sem acesso para classes ou métodos (mas nunca variáveis). Marcar uma classe como strictfpsignifica que qualquer código de método da classe estará em conformidade com as regras padrão IEEE 754 para pontos flutuantes.

Sem esse modificador, os pontos flutuantes usados ​​nos métodos podem se comportar de maneira dependente da plataforma. Com ele, é possível prever como seus pontos flutuantes se comportarão, independentemente da plataforma subjacente na qual a JVM está sendo executada. A desvantagem é que, se a plataforma subjacente for capaz de suportar maior precisão, um strictfpmétodo não poderá tirar proveito dela.

Se você não declarar uma classe como strictfp, ainda poderá obter um strictfpcomportamento método por método, declarando um método como strictfp.

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


0

O exemplo abaixo pode ajudar a entender isso de forma mais clara: Em java, sempre que estamos usando, procurando informações precisas para qualquer operação, por exemplo, se fizermos o dobro num1 = 10e + 102; num2 duplo = 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.

0

A palavra-chave 'strictfp' é usada para forçar a precisão dos cálculos de ponto flutuante (flutuante ou duplo) em Java, em conformidade com o padrão 754 da IEEE, explicitamente. Se você não usar a palavra-chave strictfp, a precisão do ponto flutuante dependerá do hardware da plataforma de destino.

Se uma interface ou classe é declarada com strictfp, todos os métodos e tipos aninhados nessa interface ou classe são implicitamente strictfp.

Referência Link de

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.