Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
In alcuni casi, quando si aggiornano i progetti a una versione più recente di Visual Studio, è possibile notare modifiche nei risultati di determinate operazioni a virgola mobile. 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). In generale, i nuovi risultati sono corretti entro i limiti specificati dal linguaggio standard. Le sezioni che seguono spiegano che cosa è cambiato e, se è importante, come ottenere gli stessi risultati che si ottenevano in precedenza.
Nuove funzioni matematiche e modifiche di Universal CRT
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. L'implementazione di queste funzioni consente di bilanciare prestazioni e correttezza. 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. Nella maggior parte dei casi, il risultato prodotto è all'interno di +/-1 unità di precisione minima, o ulp, del risultato arrotondato correttamente, anche se in alcuni casi è presente una maggiore imprecisione. Se è stata usata una libreria matematica diversa per ottenere queste funzioni in precedenza, le differenze di implementazione potrebbero spiegare la modifica nei risultati.
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. Le modifiche possono comportare differenze rilevabili nei risultati dei calcoli a virgola mobile che usano queste funzioni. Le funzioni con problemi di bug erano erf, exp2, remainderremquo, , scalblne scalbne le relative varianti float e long double. Altre modifiche apportate a Visual Studio 2015 hanno risolto problemi di mantenimento delle informazioni sulla parola di stato a virgola mobile e sullo stato delle eccezioni nelle funzioni _clear87, _clearfp, fegetenv, fesetenv e feholdexcept.
Differenze del processore e flag del compilatore
Molte delle funzioni della libreria delle operazioni matematiche a virgola mobile hanno implementazioni diverse per architetture della CPU differenti. La versione di CRT x86 a 32 bit, ad esempio, può avere un'implementazione diversa di CRT x64 a 64 bit. Alcune funzioni potrebbero inoltre avere più implementazioni per una particolare architettura della CPU. L'implementazione più efficiente viene selezionata in modo dinamico in fase di esecuzione a seconda del set di istruzioni supportate dalla CPU. Ad esempio, in CRT x86 a 32 bit alcune funzioni hanno sia un'implementazione x87 che un'implementazione SSE2. In caso di esecuzione su una CPU che supporta SSE2, viene usata l'implementazione SSE2 più veloce. Quando si esegue su una CPU che non supporta SSE2, viene usata l'implementazione x87 più lenta. 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. 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. 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.
I miglioramenti della generazione del codice in varie modalità a virgola mobile possono anche modificare i risultati a virgola mobile quando si confronta il codice precedente con il nuovo codice, anche con flag del compilatore identici. Ad esempio, il codice generato da Visual Studio 2010 quando /fp:precise (impostazione predefinita) o /fp:strict è stato specificato potrebbe non propagare correttamente i valori intermedi non numerici (NaN) tramite espressioni. Di conseguenza, alcune espressioni che restituivano un risultato numerico nei compilatori precedenti ora possono restituire correttamente un risultato NaN. È anche possibile rilevare delle differenze perché le ottimizzazioni del codice abilitate per /fp:fast ora sfruttano un maggior numero di funzionalità del processore. 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.
Come ottenere risultati identici
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. È possibile riscontrare addirittura prestazioni migliori del processore in termini di risparmio di energia quando le istruzioni SSE2 sostituiscono le istruzioni x87. Tuttavia, se si dispone di codice che deve replicare con precisione il comportamento a virgola mobile di un compilatore più vecchio, prendere in considerazione l'uso di funzionalità native di multitargeting di Visual Studio e compilare il progetto interessato con gli strumenti di compilazione precedenti. Per altre informazioni, vedere Usare multitargeting nativo in Visual Studio per compilare progetti precedenti.
Vedi anche
Aggiornamento di progetti da versioni precedenti di Visual C++
Panoramica dei potenziali problemi di aggiornamento (Visual C++)
Cronologia delle modifiche di Visual C++ dal 2003 al 2015