Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Às vezes, quando você atualiza seus projetos para uma versão mais recente do Visual Studio, você pode notar alterações nos resultados de determinadas operações de ponto flutuante. Isso geralmente acontece por um de dois motivos: alterações na geração de código que aproveitam melhor o processador disponível e correções de bugs ou alterações nos algoritmos usados em funções matemáticas na biblioteca de tempo de execução C (CRT). Em geral, os novos resultados estão corretos dentro dos limites especificados pelo padrão de idioma. Continue lendo para descobrir o que mudou e, se for importante, como obter os mesmos resultados que suas funções obtinham antes.
Novas funções matemáticas e mudanças CRT universais
A maioria das funções matemáticas CRT estão disponíveis no Visual Studio há anos, mas a partir do Visual Studio 2013, todas as funções exigidas pela ISO C99 estão incluídas. Estas funções são implementadas para equilibrar o desempenho com a correção. Como produzir o resultado arredondado corretamente em todos os casos pode ser proibitivamente caro, essas funções são projetadas para produzir eficientemente uma aproximação próxima ao resultado arredondado corretamente. Na maioria dos casos, o resultado produzido está dentro de +/-1 unidade de menor precisão, ou ulp, do resultado arredondado corretamente, embora possa haver casos em que haja maior imprecisão. Se você usou uma biblioteca de matemática diferente para obter essas funções anteriormente, as diferenças de implementação podem explicar a alteração nos resultados.
Quando as funções matemáticas foram movidas para o CRT Universal no Visual Studio 2015, alguns novos algoritmos foram usados e vários bugs na implementação das funções que eram novas no Visual Studio 2013 foram corrigidos. Essas alterações podem levar a diferenças detetáveis nos resultados de cálculos de vírgula flutuante que usam essas funções. As funções que tinham problemas de bug eram erf, exp2, remainder, remquo, scalbln, e , e scalbnsuas variantes flutuantes e duplas longas. Outras alterações no Visual Studio 2015 corrigiram problemas na preservação de informações de status de ponto flutuante e estado de exceção em _clear87, _clearfp, fegetenv, fesetenve feholdexcept funções.
Diferenças de processador e sinalizadores do compilador
Muitas das funções da biblioteca matemática de ponto flutuante têm implementações diferentes para diferentes arquiteturas de CPU. Por exemplo, a CRT x86 de 32 bits pode ter uma implementação diferente da CRT x64 de 64 bits. Além disso, algumas das funções podem ter várias implementações para uma determinada arquitetura de CPU. A implementação mais eficiente é selecionada dinamicamente em tempo de execução, dependendo dos conjuntos de instruções suportados pela CPU. Por exemplo, no CRT x86 de 32 bits, algumas funções têm uma implementação x87 e uma implementação SSE2. Ao executar em uma CPU que suporta SSE2, a implementação SSE2 mais rápida é usada. Quando executado em uma CPU que não suporta SSE2, a implementação x87 mais lenta é usada. Você pode ver isso ao migrar o código antigo, porque a opção de arquitetura do compilador x86 padrão foi alterada para /arch:SSE2 no Visual Studio 2012. Como diferentes implementações das funções da biblioteca de matemática podem usar instruções de CPU diferentes e algoritmos diferentes para produzir seus resultados, as funções podem produzir resultados diferentes em plataformas diferentes. Na maioria dos casos, os resultados estão dentro de +/-1 ulp do resultado arredondado corretamente, mas os resultados reais podem variar entre CPUs.
Melhorias na geração de código em vários modos de ponto flutuante também podem alterar os resultados de ponto flutuante ao comparar o código antigo com o novo código, mesmo com sinalizadores de compilador idênticos. Por exemplo, o código gerado pelo Visual Studio 2010 quando /fp:precise (o padrão) ou /fp:strict foi especificado pode não propagar valores intermediários não-a-número (NaN) por meio de expressões corretamente. Assim, algumas expressões que deram um resultado numérico em compiladores mais antigos podem agora produzir corretamente um resultado NaN. Você também pode ver diferenças porque as otimizações de código ativadas para /fp:fast agora aproveitam mais recursos do processador. Essas otimizações podem usar menos instruções, mas podem afetar os resultados gerados porque algumas operações intermediárias anteriormente visíveis foram removidas.
Como obter resultados idênticos
Na maioria dos casos, as alterações de ponto flutuante nos compiladores e bibliotecas mais recentes resultam em um comportamento mais rápido ou mais correto, ou ambos. Você pode até ver um melhor desempenho de energia do processador quando as instruções SSE2 substituem as instruções x87. No entanto, caso haja código que precise replicar com precisão o comportamento de ponto flutuante de um compilador mais antigo, considere utilizar as capacidades nativas de multidestino do Visual Studio e construir o projeto afetado com as ferramentas de compilação antigas. Para obter mais informações, consulte Usar a funcionalidade de multi-targeting nativa no Visual Studio para compilar projetos antigos.
Ver também
Atualizando projetos de versões anteriores do Visual C++
Visão geral de possíveis problemas de atualização (Visual C++)
Histórico de alterações do Visual C++ 2003 - 2015