We have been programming the control software for cutting machine since many years. We are developing for Windows only and using Visual Studio 2015 and Qt5.6. Since we plan to distribute our SW as 64bit we have some problems with certain automated test where we compare our output text files vs. a test set.
Tracking down the problem I could see that trigometric (par example sin()) function from seems to be hw dependent. I am aware that floating point calculation have some uncertainty and every fp types has its own precision. Also I am aware that different cpu have different architecture (fpu, register, etc.) and therefore different behaviour. In x86 we used the floating point model /fp:precise which forced the compiler to build consistent instruction code. However in x64, the fp models flag are ignored and I can see that the same assembler instruction delivers different results on my i7 laptop and on the build server xeon e5 cpu. See assembler debug output of my attached test code. x64 debug on build slave (xeon e5) vs. x64 debug on my laptop (i7) This behaviour we can observe on certain values and it looks like it has to do with how the cpu/fpu handles the floating points. As I understood floating point, precision does not explain this inconsistency (change of last digit). For all calculation we use double. In my researches on this topic, I found a lot of stuff about similar issues when win32 compiling, saying that the internal precision used in Intel x86 CPU caused this difference. It could be fixed by setting floating point model /fp:precise. However, there seems not a lot of usefull stuff for this on x64.
As we chain up a lot of calculations, the failure propagates itself and becomes more and more significant. Anyway, propably I could fix the problem with changing the automated test and verify the calculation instead of string compare by checking if the results are within certain %-range. This would cause some refactoring in automated test. Furthermore I do not have a good feeling about this whole issue because I can not explain it. Hence I would like know:
- Why this happens with x64 compilation?
How can I fix it? Compiler settings, using different math library (which),...
**
include "stdafx.h"
#include <cmath>//"math.h" #include <stdio.h> #include <iostream> #include <float.h> #include <fstream> #include <windows.h> #include <tchar.h> #include <iomanip> #include "../../../../../../../Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE/string" //#include "xpfpa.h" //#include "Winbase.h" using namespace std; #pragma fenv_access (on) int main() { string fileName = ""; // Check windows #if _WIN32 || _WIN64 #if _WIN64 #define ENVIRONMENT64 #else #define ENVIRONMENT32 #endif #endif #ifdef ENVIRONMENT64 fileName = "X64"; #else fileName = "X86"; #endif #define INFO_BUFFER_SIZE 32767 TCHAR infoBuf[INFO_BUFFER_SIZE]; DWORD bufCharCount = INFO_BUFFER_SIZE; // Get and display the name of the computer. if (!GetComputerName(infoBuf, &bufCharCount)) cout << (TEXT("GetComputerName")); //_tprintf(TEXT("\nComputer name: %s"), infoBuf); fileName += "_"; wstring compNameW(&infoBuf[0]); //convert to wstring string compName(compNameW.begin(), compNameW.end()); //and convert to string. fileName += compName; fileName += ".txt"; printf("writing %s ... ", fileName.c_str()); ofstream myfile; myfile.open(fileName); // Get and display the user name. SYSTEM_INFO siSysInfo; // Copy the hardware information to the SYSTEM_INFO structure. GetSystemInfo(&siSysInfo); // Display the contents of the SYSTEM_INFO structure. myfile << "Hardware information: \n"; myfile << " OEM ID: " << siSysInfo.dwOemId << "\n"; myfile << " Number of processors: " << siSysInfo.dwNumberOfProcessors << "\n"; myfile << " Page size: " << siSysInfo.dwPageSize << "\n"; myfile << " Processor type: " << siSysInfo.dwProcessorType << "\n"; myfile << " Minimum application address: " << siSysInfo.lpMinimumApplicationAddress << "\n"; myfile << " Maximum application address: " << siSysInfo.lpMaximumApplicationAddress << "\n"; myfile << " Active processor mask: " << siSysInfo.dwActiveProcessorMask << "\n"; myfile << " Prozessor: " << siSysInfo.dwProcessorType << "\n"; // Get and display the user name. if (!GetUserName(infoBuf, &bufCharCount)) cout << (TEXT("GetUserName")); myfile << " User name: " << infoBuf << "\n"; double a = 0.1; unsigned int control_word; int err; // Show original FP control word and do calculation. _controlfp_s(&control_word, 0, 0); myfile << " Original controlWord: " << control_word << "\n"; //XPFPA_SWITCH_DOUBLE_EXTENDED() double angle[572] = { -3.0433482797893871563, -2.8996586887582869174, -2.8085148806578694725, -2.7222381633207075602, -2.6414345623786013029, -2.5663768497517609468, -2.4970681509375158846, -2.4333158242742154442, -2.3748004015428270108, -2.3211319006474169235, -2.2718915465838427359, -2.2266602213456976322, -2.1850363031976076655, -2.1285302693875700619, -2.0782802269842535203, -2.0477766908994761152, -2.005988174897452847, -1.9564494133128236264, -1.9126587369459628896, -1.873457039790540346, -1.8379373648338011016, -1.8053838423691523918, -1.7752255056124330856, -1.7470772220391239671, -1.7205972190315561576, -1.6955175359472745011, -1.6715367216746777057, -1.6370508515541948302, -1.5926855563655908377, -1.5489070972242025004, -1.5045418020355980637, -1.4700559319151131898, -1.4460751176425172826, -1.4209954345582358481, -1.3945154315506684828, -1.3663671479773658035, -1.3362088112206378376, -1.303655288755994679, -1.2681356137992498834, -1.2289339166438335571, -1.1851432402769703778, -1.1356044786923491507, -1.0938159626903252164, -1.0633124266055451468, -1.0130623842022061787, -0.95655635039223041449, -0.9149324322440782753, -0.86970110700594416286, -0.82046075294245079945, -0.76679225204696188634, -0.70827682931560831392, -0.64452450265227778647, -0.5752158038380108529, -0.50015809121119547687, -0.4193544902690680698, -0.33307777293199641866, -0.24193396483144608, -0.098244373800405251917, 0.098246592598153353881, 0.2419391755490098439, 0.33308455926423430338, 0.41936243259553934726, 0.50016675058393433861, 0.57522475996069100113, 0.64453337819516354212, 0.70828530160366642843, 0.76680005532070405483, 0.82046767473287085526, 0.86970698153528180896, 0.9149371328508182355, 0.95655978216497161704, 1.0130637770694810307, 1.0633124266055327123, 1.0938159626903014576, 1.1356044786923560341, 1.1851432402769723762, 1.2289339166438206785, 1.2681356137992438882, 1.3036552887559991198, 1.336208811220639836, 1.3663671479773606965, 1.3945154315506667064, 1.4209954345582336277, 1.4460751176425197251, 1.4700559319151145221, 1.5045418020355980637, 1.5489070972242029445, 1.5926855563655899495, 1.6370508515541959405, 1.6715367216746777057, 1.695517535947273613, 1.7205972190315566017, 1.7470772220391261875, 1.7752255056124304211, 1.8053838423691579429, 1.837937364833798215, 1.8734570397905456751, 1.9126587369459568944, 1.9564494133128234044, 2.0059881748974395244, 2.047776690899469898, 2.0782802269842499676, 2.1285288765203120853, 2.1850328714248230533, 2.2266555207389542304, 2.271885672054521077, 2.321124978856943688, 2.3747925982690616387, 2.4333073519860937139, 2.4970592753946365683, 2.5663678936290801325, 2.6414259030058899747, 2.7222302209942204065, 2.8085080943256390817, 2.8996534780407294818, 3.0433460609916402895, 3.0415926535897748195, 2.8467432816694220321, 2.7523132476245502076, 2.7467432816694219433, 2.7523132476245502076, 2.6647029410266949156, 2.6523132476245501188, 2.6647029410266949156, 2.579683872810047518, 2.5031679332016967265, 2.4296120926562183584, 2.3645064581329338083, 2.302202810172837566, 2.2473823863653894506, 2.1949701996596511222, 2.1488011444494228286, 2.1046019058947580405, 2.0626653414541200604, 1.9944121463226256452, 1.9622126685901970511, 1.9315735849007600322, 1.8804027648941168405, 1.8327714052705215142, 1.7925460686214300665, 1.754537581165664939, 1.7213371485019617335, 1.689539204606653966, 1.6609352327506483604, 1.6332989516959666165, 1.6078954863671903741, 1.5831983785336045667, 1.559875064815740453, 1.5145747859362590493, 1.4707963267948995778, 1.4145747859362591825, 1.370796326794899711, 1.3145747859362590937, 1.2707963267948996222, 1.2145747859362590049, 1.1707963267948997554, 1.1145747859362591381, 1.0707963267948996666, 1.0145747859362592713, 0.97079632679489968883, 0.91457478593625918251, 0.87079632679489971103, 0.81457478593625909369, 0.77079632679489962221, 0.71457478593625911589, 0.67079632679489964442, 1.57079632679489678, 1.559875064815740453, 1.5145747859362788112, 1.4273660152971587856, 1.3817175887740413831, 1.3584530680624329335, 1.3336971672226389796, 1.3083734422622157467, 1.2806808469715929011, 1.2521621173534696059, 1.2202555050878285403, 1.1872246426301178435, 1.1490465849683673127, 1.1090965918582795791, 1.0611898886956727672, 1.0082519403809893088, 0.97944434594385898496, 0.94720024200335728448, 0.87612881663487418571, 0.83708275656112396401, 0.79279150914033258424, 0.74672508224126921128, 0.69421026722450540625, 0.63948440775057413532, 0.57708619545684625152, 0.51202479953317692196, 0.43842472038825908154, 0.36183515262818033431, 0.27688971256307493007, 0.26183515262818035652, 0.27688971256307493007, 0.18902897917758879065, 0.17688971256307489677, 0.18902897917758879065, 0.09649318519633964808, 0.09649318519633964808, -0.099999999999981076249, -0.0035068148036603574713, -0.1999999999999810818, -0.10350681480366033527, -0.2999999999999810596, -0.20350681480366036857, -0.3999999999999810929, -0.30350681480366037412, -0.4999999999999810707, -0.40350681480366035192, -0.59999999999998099298, -0.50350681480366032972, -0.69999999999998097078, -0.60350681480366041853, -0.7999999999999810596, -0.70350681480366039633, -0.89999999999998103739, 8.3266726846886740532e-16, 0.18902897917758879065, 0.096490966398555783057, 0.096490966398555783057, -0.29484508556892286002, -0.38927325484833119607, -0.39484508556892283782, -0.38927325484833119607, -0.47688229101536649956, -0.48927325484833122937, -0.47688229101536649956, -0.56190032315460447521, -0.6384158592678261801, -0.71197152399804841671, -0.77707748130659726193, -0.83938162656427650621, -0.89420287752994354058, -0.94661600989835026354, -0.99278620411343088126, -1.0369866577818922515, -1.0789245264010569603, -1.1471805072672820458, -1.1793799849995274531, -1.2100190686890170966, -1.2611898886956769417, -1.3088212483192762647, -1.3490465849683896948, -1.3870550724240957585, -1.4202555050878500342, -1.4520534489831493641, -1.4806574208391480862, -1.5082937018938800122, -1.5336971672225718777, -1.5583942750562036483, -1.5817175887740404505, -1.6270178676535327345, -1.6707963267949201835, -1.7270178676535326012, -1.7707963267949200503, -1.82701786765353269, -1.8707963267949201391, -1.9270178676535327789, -1.9707963267949200059, -2.0270178676535328677, -2.0707963267949200947, -2.1270178676535325124, -2.1707963267949201835, -2.2270178676535326012, -2.2707963267949198283, -2.32701786765353269, -2.3707963267949203612, -2.4270178676535327789, -2.4707963267949200059, -1.5707963267948961139, -1.5817175887740404505, -1.6270178676535078655, -1.7142266382926427681, -1.7598750648157730492, -1.7831395855273337592, -1.8078954863671412578, -1.8332192113275984635, -1.8609118066181729034, -1.8894305362363632561, -1.9213371485019226093, -1.9543680109596928141, -1.992546068621409594, -2.0324960617315372957, -2.080402764894136336, -2.1333407132088071378, -2.1621483076459360184, -2.1943924115864659186, -2.2654666105872451887, -2.3045139932150995321, -2.3488064494762737056, -2.3948740252348343915, -2.4473897760600111795, -2.5021164762651801894, -2.5645151722833166019, -2.6295769051813611128, -2.7031767943220486039, -2.7797659640671539272, -2.8647103625742662558, -2.879765964067154016, -2.8647103625742662558, -2.9525698094956531747, -2.9647103625742663446, -2.9525698094956531747, -3.0451039059889635219, -3.0433482797893871563, -2.8996586887582869174, -2.8085148806578694725, -2.7222381633206995666, -2.6414345623786075201, -2.5663768497517609468, -2.4970681509375158846, -2.4333158242742309874, -2.3748004015428203495, -2.3211319006473920545, -2.2718915465838374068, -2.2266602213456976322, -2.1850363031976076655, -2.1285302693875727265, -2.078280226984246859, -2.0477766908994703421, -2.0059881748974417448, -1.9564494133128202957, -1.9126587369459586707, -1.8734570397905336847, -1.8379373648338011016, -1.8053838423691548343, -1.7752255056124277566, -1.7470772220391281859, -1.7205972190315563797, -1.6955175359472745011, -1.6715367216746794821, -1.6370508515541968286, -1.5707963267948958919, -1.5045418020355971755, -1.4700559319151131898, -1.4460751176425179487, -1.4209954345582391788, -1.3945154315506675946, -1.3663671479773642492, -1.336208811220639836, -1.3036552887559960112, -1.268135613799243, -1.2289339166438195683, -1.1851432402769703778, -1.1356044786923491507, -1.0938159626903127819, -1.0633124266055475893, -1.0130623842021984071, -0.95655635039219788496, -0.91493243224409481762, -0.86970110700596781061, -0.82046075294242892806, -0.76679225204698586715, -0.70827682931556645851, -0.64452450265226424175, -0.57521580383801340641, -0.50015809121119547687, -0.4193544902690680698, -0.33307777293198825852, -0.24193396483144608, 1.1102230246251565404e-16, 0.2419391755490098439, 0.33308455926423430338, 0.41936243259553834806, 0.50016675058393045283, 0.57522475996068012094, 0.64453337819516354212, 0.70828530160366642843, 0.76680005532072625929, 0.82046767473290371786, 0.869706981535252166, 0.91493713285080491282, 0.95655978216498127598, 1.013063777069502569, 1.0633124266055649088, 1.0938159626903052324, 1.1356044786923513712, 1.1851432402769723762, 1.2289339166438355555, 1.2681356137992485511, 1.303655288755990016, 1.3362088112206353951, 1.366367147977368246, 1.3945154315506660403, 1.4209954345582371804, 1.4460751176425197251, 1.4700559319151145221, 1.5045418020355967315, 1.570796326794896558, 1.6370508515541957184, 1.6715367216746777057, 1.695517535947273613, 1.7205972190315599324, 1.7470772220391261875, 1.7752255056124288668, 1.8053838423691563886, 1.837937364833798437, 1.8734570397905456751, 1.912658736945955118, 1.9564494133128176312, 2.0059881748974395244, 2.0477766908994716744, 2.0782802269842632903, 2.1285288765203058681, 2.1850328714248230533, 2.2266555207389768789, 2.2718856720545121952, 2.3211249788569365826, 2.3747925982690545332, 2.4333073519861243561, 2.4970592753946339037, 2.5663678936290801325, 2.6414259030058704347, 2.7222302209942266238, 2.8085080943256390817, -3.0433482797893871563, -2.8535758972990263871, -2.681152308789283456, -2.5310191384297882067, -2.4034208777577394933, -2.2959698207245691215, -2.2054006923714797317, -2.1285302693875700619, -2.0627648571219414642, -2.005988174897452847, -1.9564494133128236264, -1.9126587369459628896, -1.873457039790540346, -1.8379373648338011016, -1.8053838423691523918, -1.7752255056124330856, -1.7470772220391239671, -1.7205972190315561576, -1.683416728001451812, -1.6370508515541948302, -1.5926855563655908377, -1.5489070972242025004, -1.5045418020355980637, -1.4581759255883395276, -1.4209954345582358481, -1.3945154315506684828, -1.3663671479773658035, -1.3362088112206378376, -1.303655288755994679, -1.2681356137992498834, -1.2289339166438335571, -1.1851432402769703778, -1.1356044786923491507, -1.0788277964678447685, -1.0130623842022061787, -0.93619196121830827728, -0.845622832865261298, -0.7381717758320278655, -0.61057351515998214975, -0.46044034480050533009, -0.28801675629077944096, -0.098244373800405251917, 0.098246592598153353881, 0.28802279786666995509, 0.46044869155366852098, 0.61058246491119927413, 0.73817993253462954595, 0.84562923787566290912, 0.93619602621075082016, 1.0130637770694810307, 1.0788277964678569809, 1.1356044786923560341, 1.1851432402769723762, 1.2289339166438206785, 1.2681356137992438882, 1.3036552887559991198, 1.336208811220639836, 1.3663671479773606965, 1.3945154315506667064, 1.4209954345582336277, 1.458175925588341082, 1.5045418020355980637, 1.5489070972242029445, 1.5926855563655899495, 1.6370508515541959405, 1.683416728001451812, 1.7205972190315566017, 1.7470772220391261875, 1.7752255056124304211, 1.8053838423691579429, 1.837937364833798215, 1.8734570397905456751, 1.9126587369459568944, 1.9564494133128234044, 2.0059881748974395244, 2.0627648571219463491, 2.1285288765203120853, 2.2959634157141572963, -3.0433482797893871563, 2.4034127210551399223, 2.5310101886785765224, 2.8085148806578694725, 2.6811439620361099401, -2.7222381633206995666, 3.0433460609916402895, -2.6414345623786013029, -2.5663768497517609468, -2.4970681509375158846, -2.4333158242742203292, -2.3748004015428318958, -2.3211319006473867255, -2.2718915465838493972, -2.2266602213457034054, -2.1850363031976076655, -2.1285302693875762792, -2.0782802269842486353, -2.0477766908994925465, -2.005988174897452847, -1.9564494133128236264, -1.9126587369459628896, -1.8734570397905410122, -1.8379373648338011016, -1.8053838423691559445, -1.7752255056124308652, -1.7470772220391268537, -1.7205972190315583781, -1.6955175359472745011, -1.6715367216746783718, -1.6370508515541948302, -1.5707963267948970021, -1.5045418020355971755, -1.4700559319151131898, -1.4460751176425175046, -1.4209954345582327395, -1.3945154315506675946, -1.3663671479773642492, -1.3362088112206371715, -1.3036552887559960112, -1.2681356137992492172, 3.0415926535897748195, -1.2289339166438224549, 2.8424367704195603324, -1.1851432402769703778, 2.6647029410267104588, -1.1356044786923491507, 2.497513919224154666, 2.3645064581330341724, -1.0938159626903127819, 2.2431256869789213404, -1.0633124266055316021, -1.0130623842022270509, -0.95655635039219200078, 1.9944121463225683577, -0.86970110700595659736, 1.9315735849007600322, 1.8804027648941168405, 1.8327714052705215142, 1.7925460686214300665, 1.754537581165664939, 1.7213371485019617335, -0.50015809121119547687, 1.689539204606653966, -0.4193544902690680698, -0.33307777293198825852, 1.6069583911871390125, 1.559875064815740453, 1.1102230246251565404e-16, 0.2419391755490098439, 1.4707963267948995778, 1.4145747859362591825, 0.41936243259553834806, 0.50016675058393045283, 1.370796326794899711, 1.3145747859362590937 }; myfile << "sin(2.4970592753946365683) is " << std::setw(24) << std::setprecision(20) << sin(2.4970592753946365683) << "\n"; double dVal = 0.77079632679489962221; double sinValue = sin(dVal); myfile << "sin(" << dVal << ") in double is " << std::setw(24) << std::setprecision(20) << sinValue << "\n"; myfile << "--- Test --- " << "\n"; for (int i = 0; i < 572; i++) { myfile << "angle: " << std::setw(24) << std::setprecision(20) << angle[i] << " ==> sin(angle): " << std::setw(24) << std::setprecision(20) << sin(angle[i]) << "\n"; } std::string input; getline(std::cin, input); myfile.close(); return 0; }