Changeset 1251 for cpp/common
- Timestamp:
- 06/22/23 03:21:19 (17 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/common/nonstd_math.cpp
r1026 r1251 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-202 0Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2023 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 30 30 (char*) 31 31 #endif 32 str.data(); //now we will be operating directly on the internal std::string buffer33 for (int i = str.length() - 1, end = str.length(); i >= 0; i--) //remove trailing zeros, and maybe also '.'32 str.data(); //now we will be operating directly on the internal std::string buffer 33 for (int i = int(str.length()) - 1, end = int(str.length()); i >= 0; i--) //remove trailing zeros, and maybe also '.' 34 34 { 35 35 if (s[i] == '0') … … 76 76 strncpy(buffer, s.c_str(), std::min(bufferlen, (int)s.length() + 1)); 77 77 buffer[bufferlen - 1] = 0; //ensure the string is truncated 78 return s.length();78 return int(s.length()); 79 79 } 80 80 } … … 91 91 92 92 93 // Idea: enable selected floating point exceptions when the app starts and disable them temporarily when dividing values in ExtValue, so that we can directly handle problematic cases there. 94 // This allows to catch problematic situations when the program performs calculations using NaN, INF etc. 95 93 96 #ifdef IPHONE 94 97 //TODO! -> ? http://stackoverflow.com/questions/12762418/how-to-enable-sigfpe-signal-on-division-by-zero-in-ios-app … … 121 124 #include <fenv.h> 122 125 123 void fpExceptInit() 124 {} 125 126 void fpExceptEnable() 127 { 128 feclearexcept(FE_DIVBYZERO); 129 feenableexcept(FE_DIVBYZERO); 130 } 131 132 void fpExceptDisable() 133 { 134 fedisableexcept(FE_DIVBYZERO); 135 } 136 137 #endif 138 139 140 141 #ifdef __BORLANDC__ 142 // there was once a problem like this: 126 static constexpr int WANTED_FP_EXCEPTIONS = FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW; 127 128 void fpExceptInit() 129 {} 130 131 void fpExceptEnable() 132 { 133 feclearexcept(WANTED_FP_EXCEPTIONS); 134 feenableexcept(WANTED_FP_EXCEPTIONS); 135 } 136 137 void fpExceptDisable() 138 { 139 fedisableexcept(WANTED_FP_EXCEPTIONS); 140 } 141 142 #endif 143 144 145 146 #if defined(__BORLANDC__) || defined(_MSC_VER) 147 148 // in Borland, there was once a problem like this: 143 149 // http://qc.embarcadero.com/wc/qcmain.aspx?d=5128 144 150 // http://www.delorie.com/djgpp/doc/libc/libc_112.html … … 150 156 // But it was resolved by restarting windows and cleaning all intermediate compilation files :o (restarting windows was the key element! restarting BC++Builder and deleting files would not help) 151 157 152 #include "log.h" 158 159 #if defined(__BORLANDC__) // adding a missing constant and a function 160 #define _MCW_EM 0x0008001f // Interrupt Exception Masks - from Visual C++'s float.h 161 162 void _controlfp_s(unsigned int* _CurrentState, unsigned int _NewValue, unsigned int _Mask) //pretends to be the real _controlfp_s() function 163 { 164 *_CurrentState = _control87(_NewValue, _Mask); 165 } 166 #endif 167 168 #if defined(_MSC_VER) 169 #pragma fenv_access (on) 170 #endif 171 172 // http://stackoverflow.com/questions/2769814/how-do-i-use-try-catch-to-catch-floating-point-errors 173 174 //#include "log.h" 153 175 154 176 unsigned int fp_control_word_std; 155 177 unsigned int fp_control_word_muted; 156 178 157 void fpExceptInit() 158 { 159 //unsigned int was=_clear87(); 160 //logPrintf("","fpExceptInit",LOG_INFO,"control87 status before clear was %08x", was); 161 fp_control_word_std = _control87(0, 0); //4978 = 1001101110010 179 180 void fpExceptInit() 181 { 182 _controlfp_s(&fp_control_word_std, 0, 0); //in Visual C++, the default value is exactly the masks listed below, and we have to turn them off to enable exceptions 162 183 // Make the new fp env same as the old one, except for the changes we're going to make 163 fp_control_word_muted = fp_control_word_std | EM_INVALID | EM_DENORMAL | EM_ZERODIVIDE | EM_OVERFLOW | EM_UNDERFLOW | EM_INEXACT; //4991 = 1001101111111 164 } 165 166 void fpExceptEnable() 167 { 168 unsigned int was = _clear87(); //trzeba czyscic zeby nie bylo exception... 169 //logPrintf("","fpExceptEnable ",LOG_INFO,"control87 status before clear was %08x", was); 170 _control87(fp_control_word_std, 0xffffffff); 171 //logPrintf("","fpExceptEnable ",LOG_INFO,"control87 flags are %08x", _control87(0, 0)); //kontrola co sie ustawilo 172 } 173 174 void fpExceptDisable() 175 { 176 unsigned int was = _clear87(); //trzeba czyscic zeby nie bylo exception... 184 fp_control_word_muted = fp_control_word_std & ~(EM_INVALID | /*EM_DENORMAL |*/ EM_ZERODIVIDE | EM_OVERFLOW /* | EM_UNDERFLOW | EM_INEXACT */); //commented out exceptions that occur during proper operation 185 } 186 187 void fpExceptEnable() 188 { 189 //_fpreset(); //not needed since we just _clearfp()... mentioned in https://stackoverflow.com/questions/4282217/visual-c-weird-behavior-after-enabling-floating-point-exceptions-compiler-b 190 unsigned int was = _clearfp(); //need to clean so that there is no exception... 191 //logPrintf("","fpExceptEnable",LOG_INFO,"control87 status before clear was %08x", was); 192 _controlfp_s(&was, fp_control_word_muted, _MCW_EM); 193 } 194 195 void fpExceptDisable() 196 { 197 //_fpreset(); //not needed since we just _clearfp()... mentioned in https://stackoverflow.com/questions/4282217/visual-c-weird-behavior-after-enabling-floating-point-exceptions-compiler-b 198 unsigned int was = _clearfp(); //need to clean so that there is no exception... 177 199 //logPrintf("","fpExceptDisable",LOG_INFO,"control87 status before clear was %08x", was); 178 _control87(fp_control_word_muted, 0xffffffff); 179 //logPrintf("","fpExceptDisable",LOG_INFO,"control87 flags are %08x", _control87(0, 0)); //kontrola co sie ustawilo 180 } 181 182 #endif 183 184 185 186 #ifdef _MSC_VER 187 //Moznaby zrobic tak jak pod linuxem czyli wlaczyc exceptiony na poczatku i wylaczac na chwile przy dzieleniu w extvalue. 188 //To by pozwoli³o na wy³apanie pod visualem z³ych sytuacji kiedy framsy licz¹ na NaN, INF itp. 189 //http://stackoverflow.com/questions/2769814/how-do-i-use-try-catch-to-catch-floating-point-errors 190 void fpExceptInit() {} 191 void fpExceptEnable() {} 192 void fpExceptDisable() {} 193 #endif 200 _controlfp_s(&was, fp_control_word_std, _MCW_EM); 201 } 202 #endif
Note: See TracChangeset
for help on using the changeset viewer.