Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Ibland när du uppgraderar dina projekt till en nyare version av Visual Studio kan det hända att resultatet av vissa flyttalsåtgärder har ändrats. Detta inträffar vanligtvis av någon av två orsaker: Kodgenereringsändringar som drar bättre nytta av den tillgängliga processorn och felkorrigeringar eller ändringar i algoritmerna som används i matematiska funktioner i C-körningsbiblioteket (CRT). I allmänhet är de nya resultaten korrekta inom de gränser som anges av språkstandarden. Läs vidare för att ta reda på vad som har ändrats, och om det är viktigt, hur du får samma resultat som dina funktioner fick tidigare.
Nya matematiska funktioner och universella CRT-ändringar
De flesta CRT-matematiska funktioner har varit tillgängliga i Visual Studio i flera år, men från och med Visual Studio 2013 ingår alla funktioner som krävs av ISO C99. Dessa funktioner implementeras för att balansera prestanda med korrekthet. Eftersom det kan vara oöverkomligt dyrt att producera det korrekt rundade resultatet är dessa funktioner utformade för att effektivt ge en nära uppskattning av det korrekt rundade resultatet. I de flesta fall är resultatet som genereras inom +/-1 enhet med minst precision, eller ulp, av det korrekt rundade resultatet, även om det kan finnas fall där det finns större felaktighet. Om du använder ett annat matematiskt bibliotek för att hämta dessa funktioner tidigare kan implementeringsskillnader vara ansvariga för ändringen av dina resultat.
När matematikfunktionerna flyttades till Universal CRT i Visual Studio 2015 användes några nya algoritmer och flera buggar i implementeringen av funktionerna som var nya i Visual Studio 2013 har åtgärdats. Dessa ändringar kan leda till detekterbara skillnader i resultatet av flyttalsberäkningar som använder dessa funktioner. Funktionerna som hade buggproblem var erf, exp2, rest, remquo, scalbln och scalbn samt deras flytande och långa dubbla varianter. Andra ändringar i Visual Studio 2015 har åtgärdat problem med att bevara information om flyttalsstatusord och undantagstillstånd i funktionerna _clear87, _clearfp, fegetenv, fesetenv och feholdexcept.
Processorskillnader och kompilatorflaggor
Många av funktionerna i matematikbiblioteket för flyttalser har olika implementeringar för olika CPU-arkitekturer. Till exempel kan 32-bitars x86 CRT ha en annan implementering än 64-bitars x64 CRT. Dessutom kan vissa av funktionerna ha flera implementeringar för en viss CPU-arkitektur. Den mest effektiva implementeringen väljs dynamiskt vid körning beroende på de instruktionsuppsättningar som stöds av processorn. I 32-bitars x86 CRT har vissa funktioner till exempel både en x87-implementering och en SSE2-implementering. När du kör på en processor som stöder SSE2 används den snabbare SSE2-implementeringen. När du kör på en processor som inte stöder SSE2 används den långsammare x87-implementeringen. Du kan se detta när du migrerar gammal kod eftersom standardalternativet x86-kompilatorarkitektur har ändrats till /arch:SSE2 i Visual Studio 2012. Eftersom olika implementeringar av matematiska biblioteksfunktioner kan använda olika CPU-instruktioner och olika algoritmer för att producera deras resultat, kan funktionerna ge olika resultat på olika plattformar. I de flesta fall ligger resultaten inom +/-1 ulp för det korrekt avrundade resultatet, men de faktiska resultaten kan variera mellan processorer.
Förbättringar av kodgenereringens korrekthet i olika flyttalslägen i Visual Studio kan också påverka resultatet av flyttalsåtgärder när gammal kod jämförs med ny kod, även när samma kompilatorflaggor används. Koden som genereras av Visual Studio 2010 när /fp:precise (standardvärdet) eller /fp:strict angavs kanske inte har spridit mellanliggande NaN-värden (not-a-number) korrekt genom uttrycken. Därför kan vissa uttryck som gav ett numeriskt resultat i äldre kompilatorer nu korrekt generera ett NaN-resultat. Du kan också se skillnader eftersom de kodoptimeringar som är aktiverade för /fp:fast tillfället drar nytta av fler processorfunktioner. Dessa optimeringar kan använda färre instruktioner, men kan påverka de genererade resultaten eftersom vissa tidigare synliga mellanliggande åtgärder har tagits bort.
Så här får du identiska resultat
I de flesta fall leder flyttalsändringarna i de senaste kompilatorerna och biblioteken till snabbare eller mer korrekt beteende, eller både och. Du kan till och med se bättre processorkraftprestanda när SSE2-instruktioner ersätter x87-instruktioner. Men om du har kod som exakt måste replikera flyttalsbeteendet för en äldre kompilator bör du överväga att använda inbyggda funktioner för flera mål i Visual Studio och skapa det berörda projektet med den äldre verktygsuppsättningen. För mer information, se Använda inbyggd multi-targeting i Visual Studio för att bygga gamla projekt.
Se även
Uppgradera projekt från tidigare versioner av Visual C++
Översikt över potentiella uppgraderingsproblem (Visual C++)
Visual C++ ändringshistorik 2003 – 2015