Não, essa não é outra pergunta "Por que (1 / 3,0) * 3! = 1" .
Ultimamente tenho lido sobre pontos flutuantes; especificamente, como o mesmo cálculo pode fornecer resultados diferentes em diferentes arquiteturas ou configurações de otimização.
Esse é um problema para jogos de vídeo que armazenam replays ou são rede ponto a ponto (em oposição ao servidor-cliente), que dependem de todos os clientes que geram exatamente os mesmos resultados sempre que executam o programa - uma pequena discrepância em um o cálculo de ponto flutuante pode levar a um estado de jogo drasticamente diferente em máquinas diferentes (ou mesmo na mesma máquina! )
Isso acontece mesmo entre os processadores que "seguem" o IEEE-754 , principalmente porque alguns processadores (ou seja, x86) usam precisão estendida dupla . Ou seja, eles usam registradores de 80 bits para fazer todos os cálculos e, em seguida, truncam para 64 ou 32 bits, levando a diferentes resultados de arredondamento do que máquinas que usam 64 ou 32 bits para os cálculos.
Eu já vi várias soluções para esse problema online, mas todas para C ++, não para C #:
- Desative o modo de precisão estendida dupla (para que todos os
double
cálculos usem IEEE-754 de 64 bits) usando_controlfp_s
(Windows),_FPU_SETCW
(Linux?) Oufpsetprec
(BSD). - Sempre execute o mesmo compilador com as mesmas configurações de otimização e exija que todos os usuários tenham a mesma arquitetura de CPU (sem reprodução entre plataformas). Como meu "compilador" é realmente o JIT, que pode otimizar diferentemente toda vez que o programa é executado , não acho que isso seja possível.
- Use aritmética de ponto fixo e evite
float
-odouble
completamente.decimal
funcionaria para esse fim, mas seria muito mais lento, e nenhuma dasSystem.Math
funções da biblioteca o suporta.
Então, isso é mesmo um problema em c #? E se eu pretender apenas suportar o Windows (não o Mono)?
Se for, existe alguma maneira de forçar meu programa a executar com precisão dupla normal?
Caso contrário, existem bibliotecas que ajudariam a manter os cálculos de ponto flutuante consistentes?
strictfp
palavra - chave, o que força todos os cálculos a serem feitos no tamanho indicado ( float
ou double
), em vez de um tamanho estendido. No entanto, o Java ainda tem muitos problemas com o suporte ao IEE-754. Muito (muito, muito) poucas linguagens de programação suportam bem o IEE-754.