Problemi relativi alla migrazione dei valori a virgola mobileFloating-point migration issues

A volte durante l'aggiornamento dei progetti a una versione più recente di Visual Studio è possibile notare che i risultati di determinate operazioni a virgola mobile sono cambiati.Sometimes when you upgrade your projects to a newer version of Visual Studio, you may find that the results of certain floating-point operations have changed. Ciò si verifica in genere per uno di questi due motivi: modifiche della generazione di codice che usano in modo più efficace il processore disponibile e correzioni di bug o modifiche degli algoritmi usati nelle funzioni matematiche della libreria di runtime C (CRT).This generally happens for one of two reasons: Code generation changes that take better advantage of the available processor, and bug fixes or changes to the algorithms used in math functions in the C runtime library (CRT). In generale, i nuovi risultati sono corretti entro i limiti specificati dal linguaggio standard.In general, the new results are correct to within the limits specified by the language standard. Le sezioni che seguono spiegano che cosa è cambiato e, se è importante, come ottenere gli stessi risultati che si ottenevano in precedenza.Read on to find out what's changed, and if it's important, how to get the same results your functions got before.

Nuove funzioni matematiche e modifiche di Universal CRTNew math functions and Universal CRT changes

La maggior parte delle funzioni matematiche di CRT sono state disponibili in Visual Studio per anni, ma a partire da Visual Studio 2013, tutte le funzioni richieste da ISO C99 sono incluse.Most CRT math functions have been available in Visual Studio for years, but starting in Visual Studio 2013, all of the functions required by ISO C99 are included. L'implementazione di queste funzioni consente di bilanciare prestazioni e correttezza.These functions are implemented to balance performance with correctness. Dato che generare un risultato con il corretto arrotondamento in ogni caso può avere costi proibitivi, queste funzioni sono progettate per ottenere in modo efficiente un'approssimazione molto vicina al risultato arrotondato correttamente.Because producing the correctly rounded result in every case may be prohibitively expensive, these functions are designed to efficiently produce a close approximation to the correctly rounded result. Nella maggior parte dei casi il risultato prodotto è compreso entro +/-1 unità di minore precisione, o ulp, rispetto al risultato arrotondato correttamente, sebbene in alcuni casi possa esistere un'imprecisione maggiore.In most cases, the result produced is within +/-1 unit of least precision, or ulp, of the correctly rounded result, though there may be cases where there is greater inaccuracy. Se si usa una libreria matematica diversa per ottenere queste funzioni prima, le differenze di implementazione possono causare la modifica dei risultati.If you were using a different math library to get these functions before, implementation differences may be responsible for the change in your results.

Quando le funzioni matematiche sono state spostate nella libreria Universal CRT in Visual Studio 2015, sono stati usati alcuni nuovi algoritmi e sono stati corretti alcuni bug nell'implementazione delle funzioni introdotte in Visual Studio 2013.When the math functions were moved to the Universal CRT in Visual Studio 2015, some new algorithms were used, and several bugs in the implementation of the functions that were new in Visual Studio 2013 were fixed. Le modifiche possono comportare differenze rilevabili nei risultati dei calcoli a virgola mobile che usano queste funzioni.These changes can lead to detectable differences in the results of floating-point calculations that use these functions. Le funzioni con problemi di bug erano erf, exp2, remainder, remquo, scalbln, scalbn e le relative varianti float e long double.The functions that had bug issues were erf, exp2, remainder, remquo, scalbln, and scalbn, and their float and long double variants. Altre modifiche in Visual Studio 2015 hanno risolto i problemi relativi alla conservazione della parola di stato a virgola mobile e delle informazioni sullo stato di eccezione nelle funzioni _clear87, _clearfp, fegetenv, fesetenv e feholdexcept.Other changes in Visual Studio 2015 fixed issues in preserving floating point status word and exception state information in _clear87, _clearfp, fegetenv, fesetenv, and feholdexcept functions.

Differenze del processore e flag del compilatoreProcessor differences and compiler flags

Molte delle funzioni della libreria delle operazioni matematiche a virgola mobile hanno implementazioni diverse per architetture della CPU differenti.Many of the floating point math library functions have different implementations for different CPU architectures. La versione di CRT x86 a 32 bit, ad esempio, può avere un'implementazione diversa di CRT x64 a 64 bit.For example, the 32-bit x86 CRT may have a different implementation than the 64-bit x64 CRT. Alcune funzioni potrebbero inoltre avere più implementazioni per una particolare architettura della CPU.In addition, some of the functions may have multiple implementations for a given CPU architecture. L'implementazione più efficiente viene selezionata in modo dinamico in fase di esecuzione a seconda del set di istruzioni supportate dalla CPU.The most efficient implementation is selected dynamically at run-time depending on the instruction sets supported by the CPU. Ad esempio, in CRT x86 a 32 bit alcune funzioni hanno sia un'implementazione x87 che un'implementazione SSE2.For example, in the 32-bit x86 CRT, some functions have both an x87 implementation and an SSE2 implementation. In caso di esecuzione su una CPU che supporta SSE2, viene usata l'implementazione SSE2 più veloce.When running on a CPU that supports SSE2, the faster SSE2 implementation is used. Per l'esecuzione su una CPU che non supporta SSE2 viene usata l'implementazione x87 più lenta.When running on a CPU that does not support SSE2, the slower x87 implementation is used. Questo può apparire quando si esegue la migrazione di codice più datato, poiché l'opzione di architettura predefinita del compilatore x86 è diventata /arch: SSE2 in Visual Studio 2012.You may see this when migrating old code, because the default x86 compiler architecture option changed to /arch:SSE2 in Visual Studio 2012. Dato che implementazioni diverse delle funzioni della libreria delle operazioni matematiche possono usare istruzioni diverse della CPU e algoritmi differenti per produrre i risultati, le funzioni possono produrre risultati diversi su piattaforme differenti.Because different implementations of the math library functions may use different CPU instructions and different algorithms to produce their results, the functions may produce different results on different platforms. Nella maggior parte dei casi, i risultati sono compresi entro +/-1 ulp rispetto al risultato arrotondato correttamente, ma i risultati effettivi possono variare tra CPU diverse.In most cases, the results are within +/-1 ulp of the correctly rounded result, but the actual results may vary across CPUs.

I miglioramenti della correttezza della generazione di codice in diverse modalità a virgola mobile in Visual Studio possono influenzare i risultati delle operazioni a virgola mobile anche quando il codice più datato viene confrontato con il nuovo codice, anche se si usano gli stessi flag del compilatore.Code-generation correctness improvements in different floating point modes in Visual Studio can also affect the results of floating-point operations when old code is compared to new code, even when using the same compiler flags. Ad esempio, il codice generato da Visual Studio 2010 se è stato specificato /fp: precise (predefinito) o /fp: strict può non aver propagato correttamente i valori intermedi non-numerici (NaN) attraverso le espressioni.For example, the code generated by Visual Studio 2010 when /fp:precise (the default) or /fp:strict was specified may not have propagated intermediate not-a-number (NaN) values through expressions correctly. Di conseguenza, alcune espressioni che restituivano un risultato numerico nei compilatori precedenti ora possono restituire correttamente un risultato NaN.Thus, some expressions that gave a numeric result in older compilers may now correctly produce a NaN result. È anche possibile rilevare delle differenze perché le ottimizzazioni del codice abilitate per /fp: fast ora sfruttano un maggior numero di funzionalità del processore.You may also see differences because the code optimizations enabled for /fp:fast now take advantage of more processor features. Tali ottimizzazioni possono usare un numero inferiore di istruzioni, ma possono influire sui risultati generati perché alcune operazioni intermedie che in precedenza erano visibili sono state rimosse.These optimizations can use fewer instructions, but may impact the generated results because some previously visible intermediate operations have been removed.

Come ottenere risultati identiciHow to get identical results

Nella maggior parte dei casi, le modifiche dei calcoli a virgola mobile nei compilatori e nelle librerie più recenti determinano un comportamento più veloce o più corretto, o entrambe le cose.In most cases, the floating-point changes in the newest compilers and libraries result in faster or more correct behavior, or both. È possibile riscontrare addirittura prestazioni migliori del processore in termini di risparmio di energia quando le istruzioni SSE2 sostituiscono le istruzioni x87.You may even see better processor power performance when SSE2 instructions replace x87 instructions. Tuttavia, se si usa un codice che deve replicare con precisione il comportamento di un compilatore precedente per i calcoli a virgola mobile, è consigliabile usare le funzionalità multitargeting native di Visual Studio e compilare il progetto interessato con il set di strumenti precedente.However, if you have code that must precisely replicate the floating point behavior of an older compiler, consider using Visual Studio native multi-targeting capabilities, and build the affected project with the older toolset. Per altre informazioni, vedere Usare multitargeting nativo in Visual Studio per compilare progetti precedenti.For more information, see Use native multi-targeting in Visual Studio to build old projects.

Vedere ancheSee also

Aggiornamento di progetti da versioni precedenti di Visual C++Upgrading Projects from Earlier Versions of Visual C++
Panoramica dei potenziali problemi di aggiornamento (Visual C++)Overview of potential upgrade issues (Visual C++)
Cronologia delle modifiche di Visual C++ dal 2003 al 2015Visual C++ change history 2003 - 2015