File: UTILS\U_VALUES.CPP

    1 //#############################################################################
    2 //                                                                           //
    3 // U_VALUES.CPP                                                              //
    4 // Subsystem: Utilities - Tools für Zahlen und Strings                       //
    5 // Deklaration: U_VALUES.H                                                   //
    6 //---------------------------------------------------------------------------//
    7 // Autoren: Thomas Kullmann, Günther Reinecker                               //
    8 // Stand:   07.11.2002                                                       //
    9 //                                                                           //
   10 //#############################################################################
   11 
   12 #include <stdio.h>  // sprintf
   13 #include <string.h> // strlen, strcpy
   14 #include <math.h> // pow, ceil, floor
   15 #include <stdlib.h> // für variable Parameteranzahl
   16 #include <stdarg.h>
   17 
   18 #include "utils\u_values.h" // SCHNITTSTELLE für diese Datei
   19 #include "utils\u_window.h" // MBINFO
   20 
   21 //--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--
   22 
   23 
   24 #ifdef _DEBUG
25 UINT TLeakPolice::s_Counter= 0;
26 #endif 27 28 //////////////////////////////////////////////////////////////////////////////// 29 // Trace 30 //////////////////////////////////////////////////////////////////////////////// 31 32 void _CURVECLASS WINAPI TraceMsg ( LPCSTR aStr ) 33 { 34 MessageBox( NULL, aStr, "Trace", MBINFO ); 35 } 36 37 void _CURVECLASS WINAPI TraceMsg ( const double aDouble ) 38 { 39 40 char buf[ _MAXLENDOUBLE + 1 ]; // + Nullterminierung 41 sprintf( buf, "%.10f", aDouble ); 42 TraceMsg(buf); 43 } 44 45 void _CURVECLASS WINAPI Trace ( LPCSTR aStr ) 46 { 47 #ifdef _DEBUG
48 const char prae[]= "TRACE: "; 49 char *buf= new char[ strlen(prae) + strlen(aStr) + 3 ]; // + "\n" + Nullterminierung 50 sprintf(buf, "%s%s\n", prae, aStr); 51 OutputDebugString( buf ); 52 _FREEOBJ(buf);
53 #endif // _DEBUG 54 } 55 56 void _CURVECLASS WINAPI TraceErr ( LPCSTR aStr ) 57 { 58 #ifdef _DEBUG
59 const char prae[]= "FEHLER: "; 60 char *buf= new char[ strlen(prae) + strlen(aStr) + 3 ]; // + "\n" + Nullterminierung 61 sprintf(buf, "%s%s\n", prae, aStr); 62 OutputDebugString( buf ); 63 _FREEOBJ(buf);
64 #endif // _DEBUG 65 } 66 67 void _CURVECLASS WINAPI Trace ( const double aDouble ) 68 { 69 #ifdef _DEBUG
70 char buf[ _MAXLENDOUBLE + 1 ]; // + Nullterminierung 71 sprintf( buf, "%.10f", aDouble ); 72 Trace(buf);
73 #endif // _DEBUG 74 } 75 76 //////////////////////////////////////////////////////////////////////////////// 77 // Runden, Abrunden von Double-Werten 78 //////////////////////////////////////////////////////////////////////////////// 79 80 double _CURVECLASS WINAPI DoubleRound ( const double aDouble, const UINT aDigits ) 81 { 82 if ( aDouble < 0 ) 83 return DoubleRoundOff( aDouble - 0.5, aDigits ); 84 else 85 return DoubleRoundOff( aDouble + 0.5, aDigits ); 86 } 87 //----------------------------------------------------------------------------- 88 89 double _CURVECLASS WINAPI DoubleRoundUp ( const double aDouble, const UINT aDigits ) 90 { 91 double corfak= pow( 10, aDigits ); //Multiplikation mit diesem Wert verschiebt das Komma nach rechts, Division nach links 92 double temp= aDouble*corfak; 93 double temp2= DoubleRoundOff(temp, 0); 94 //Aufrunden durch Überprüfung der Nachkommastelle 95 if ( aDouble < 0 ) { 96 if ( temp2-temp>=0.09 ) temp2++; 97 } else { 98 if ( temp-temp2>=0.09 ) temp2++; 99 } 100 //Komma zurück an seine ursprüngliche Position 101 return temp2 / corfak; 102 } 103 //----------------------------------------------------------------------------- 104 105 double _CURVECLASS WINAPI DoubleRoundOff ( const double aDouble, const UINT aDigits ) 106 { 107 double temp, corfak= pow( 10, aDigits ); //Multiplikation mit diesem Wert verschiebt das Komma nach rechts, Division nach links 108 //abrunden durch Verwerfen der Nachkommastellen 109 if ( aDouble < 0 ) 110 temp= ceil( aDouble * corfak ); 111 else 112 temp= floor( aDouble * corfak ); 113 //Komma zurück an seine ursprüngliche Position 114 return temp / corfak; 115 } 116 //----------------------------------------------------------------------------- 117 118 float _CURVECLASS WINAPI Double2Float ( const double aDouble, const UINT aDigits ) 119 { 120 double temp= aDouble * pow((double)10, (double)aDigits); 121 float result= (float)temp; 122 return result / powf((float)10, (float)aDigits); 123 } 124 //----------------------------------------------------------------------------- 125 126 double _CURVECLASS WINAPI Float2Double ( const float aFloat, const UINT aDigits ) 127 { 128 float temp= aFloat * powf((float)10, (float)aDigits); 129 double result= (double)temp; 130 return result / pow((double)10, (double)aDigits); 131 } 132 133 //////////////////////////////////////////////////////////////////////////////// 134 // Stringmanipulation 135 //////////////////////////////////////////////////////////////////////////////// 136 137 LPSTR _CURVECLASS WINAPI GetFormatedString( LPCSTR aFormat, ... ) 138 { 139 va_list args; 140 va_start( args, aFormat ); 141 char *result= GetFormatedStringMaxLen( aFormat, 256, args ); 142 va_end( args ); 143 return result; 144 } 145 LPSTR _CURVECLASS WINAPI GetFormatedString( LPCSTR aFormat, va_list &args ) 146 { 147 return GetFormatedStringMaxLen( aFormat, 256, args ); 148 } 149 //----------------------------------------------------------------------------- 150 151 LPSTR _CURVECLASS WINAPI GetFormatedStringMaxLen( LPCSTR aFormat, const UINT aMaxLen, ... ) 152 { 153 va_list args; 154 va_start( args, aMaxLen ); 155 char *buf= GetFormatedStringMaxLen( aFormat, aMaxLen, args ); 156 va_end( args ); 157 return buf; 158 } 159 LPSTR _CURVECLASS WINAPI GetFormatedStringMaxLen( LPCSTR aFormat, const UINT aMaxLen, va_list &args ) 160 { 161 char *buf= 0; 162 buf= new char [ aMaxLen+1 ]; 163 vsprintf( buf, aFormat, args ); 164 return buf; 165 } 166 167 //////////////////////////////////////////////////////////////////////////////// 168 // Stringmanipulation und "Ist String ein Double?" 169 //////////////////////////////////////////////////////////////////////////////// 170 171 void _CURVECLASS WINAPI StringReplace ( char *aString, const char aOld, const char aNew ) 172 { 173 if ( !aString ) 174 return; //Leerstring, nichts zu tun 175 176 for ( UINT i= 0; i < strlen(aString); i++ ) 177 if ( aString[i] == aOld ) 178 aString[i]= aNew; 179 } 180 //----------------------------------------------------------------------------- 181 182 void _CURVECLASS WINAPI StringIgnore ( char *aString, const char aIgnore ) 183 { 184 if ( !aString || aIgnore=='\0' ) 185 return; // Leerstring oder zu ignorierendes Zeichen ist Nullterminierung: nichts zu tun 186 187 for ( UINT i= 0; i < strlen(aString); ) 188 if ( aString[i] == aIgnore ) { 189 for ( UINT j= i+1; j < strlen(aString); j++ ) 190 aString[j-1]= aString[j]; 191 aString[strlen(aString)-1]= '\0'; 192 // i nicht erhoehen, Stelle <i> nochmal prüfen, wurde ja geändert 193 } else i++; 194 } 195 //----------------------------------------------------------------------------- 196 197 int _CURVECLASS WINAPI DoubleErr ( LPCSTR aString, const char aDecimal, const char aThousand ) 198 { 199 if ( (!aString) || (strlen(aString)==0) ) 200 return 1; //Leerstring ist kein Double 201 202 char *temp= new char[strlen(aString)+1]; // + Nullterminierung 203 strcpy(temp, aString); 204 if ( aThousand!='\0' ) StringIgnore( temp, aThousand ); 205 206 BOOL foundDecimal= FALSE; 207 for ( UINT i= 0; i < strlen(temp); i++ ) 208 { 209 if ( temp[i] == aDecimal ) 210 { 211 if ( foundDecimal ) 212 return i; //zu viele Kommata 213 else 214 foundDecimal= TRUE; 215 } 216 else if ( temp[i] == '-' ) 217 { 218 if ( i > 0 ) 219 return i; //ungültiges Minuszeichen 220 } 221 else if ( (temp[i] == '0') || (temp[i] == '1') || (temp[i] == '2') || (temp[i] == '3') || (temp[i] == '4') || 222 (temp[i] == '5') || (temp[i] == '6') || (temp[i] == '7') || (temp[i] == '8') || (temp[i] == '9') ) 223 { 224 //darf überall stehen 225 } 226 else 227 return i; //ungültiges Zeichen 228 } 229 return -1; 230 } 231 //----------------------------------------------------------------------------- 232 233 BOOL _CURVECLASS WINAPI IsDouble ( LPCSTR aString, const char aDecimal, const char aThousand ) 234 { 235 return ( DoubleErr( aString, aDecimal, aThousand ) == -1 ); //keine fehlerhafte Stelle 236 } 237 238 //////////////////////////////////////////////////////////////////////////////// 239 // Konvertierung zwischen String und Double 240 //////////////////////////////////////////////////////////////////////////////// 241 242 double _CURVECLASS WINAPI String2Double ( LPCSTR aString, const UINT aDigits, const BOOL aRound, const char aDecimal, const char aThousand ) 243 { 244 char *temp= new char[ strlen(aString) + 2 ]; // + Nullterminierung und neue "0" vor dem Komma 245 strcpy( temp, aString ); 246 StringReplace( temp, aDecimal, '.' ); 247 if ( aThousand!='\0' ) StringIgnore( temp, aThousand ); 248 double aResult= atof( temp ); //im Gegensatz zu sscanf mit Double-Genauigkeit 249 _FREELIST(temp); 250 if ( aRound ) 251 return DoubleRound( aResult, aDigits ); 252 else 253 return DoubleRoundOff( aResult, aDigits ); 254 } 255 //----------------------------------------------------------------------------- 256 257 UINT GetDigits(const double aDouble) 258 { 259 if ( fabs(aDouble)>=100 ) return 0; 260 else if ( fabs(aDouble)>=10 ) return 1; 261 else if ( fabs(aDouble)>=1 ) return 2; 262 else if ( fabs(aDouble)>=0.5 ) return 3; 263 else if ( fabs(aDouble)>=0.25 ) return 4; 264 else return 5; 265 } 266 267 void _CURVECLASS WINAPI Double2String ( char *aReturn, const double aDouble, UINT aDigits, const BOOL aRound, const char aDecimal, const char aThousand ) 268 { 269 if ( aDigits>=NKAUTO ) aDigits= GetDigits(aDouble) + (aDigits-NKAUTO); 270 double temp= aDouble; 271 if ( !aRound ) 272 temp= DoubleRoundOff( aDouble, aDigits ); //sprintf rundet automatisch 273 //in String konvertieren 274 char format[6]; 275 sprintf( format, "%%.%df", aDigits ); //z.B. "%.3f" / "%.5f" -> Float-Werte mit drei / fünf Nachkommastellen 276 sprintf( aReturn, format, temp ); //aValue konvertiert als String (Nachkommastellengenauigkeit: <aDigits>) 277 StringReplace( aReturn, '.', aDecimal ); 278 if ( aThousand!='\0' ) { // Tausenderpunkte setzen 279 // Position des Komma suchen (wenn keines, Ende der Zeichenkette nehmen) 280 bool foundDecimal= false; 281 UINT decimal= 0; 282 for (UINT i= 0; i<strlen(aReturn); i++) if ( aReturn[i]==aDecimal ) { 283 decimal= i; 284 foundDecimal= true; 285 break; 286 } 287 if ( !foundDecimal ) decimal= strlen(aReturn); // wenn kein Komma, letzte Position nehmen 288 289 // Tausendertrennzeichen einfügen 290 i= decimal; 291 while (i>=0) { 292 if ( aReturn[i]=='-' ) { 293 break; 294 } else if ( decimal-i==3 && i>0 && aReturn[i-1]!='-' ) { // Tausendertrennzeichen soll gesetzt werden (aber nicht direkt vor einem Minus!) 295 aReturn[strlen(aReturn)+1]= '\0'; 296 for ( UINT j= strlen(aReturn); j>=i; j-- ) aReturn[j+1]= aReturn[j]; 297 aReturn[i]= aThousand; 298 decimal= i; // so behandeln, als ob hier ein Komma steht; dann können wir einfach mit konstantem Anstand von 3 rechnen 299 } 300 if ( i>0 ) i--; 301 else break; 302 } 303 } 304 } 305 //////////////////////////////////////////////////////////////////////////////// 306 // Formatierte Zeitausgabe 307 //////////////////////////////////////////////////////////////////////////////// 308 309 void _CURVECLASS WINAPI GetTimeString( char *aReturn, long aMillSec ) 310 { 311 sprintf( (LPSTR)aReturn, "%02d:%02d:%02d", (int)(aMillSec / 3600000l), (int)(aMillSec / 60000l) % 60, (int)(aMillSec / 1000l) % 60 ); 312 } 313 314 //Datum: 16.08.2002 315 //////////////////////////////////////////////////////////////////////////////// 316 // Min, Max 317 //////////////////////////////////////////////////////////////////////////////// 318 319 BOOL _CURVECLASS WINAPI SetInRange( double &aValue, double aBorder1, double aBorder2 ) 320 { 321 if ( aBorder1 < aBorder2 ) 322 { 323 if ( aValue < aBorder1 ) 324 { 325 aValue= aBorder1; 326 return FALSE; 327 }; 328 if ( aValue > aBorder2 ) 329 { 330 aValue= aBorder2; 331 return FALSE; 332 }; 333 } 334 else 335 { 336 if ( aValue > aBorder1 ) 337 { 338 aValue= aBorder1; 339 return FALSE; 340 }; 341 if (aValue < aBorder2) 342 { 343 aValue= aBorder2; 344 return FALSE; 345 }; 346 }; 347 return TRUE; 348 } 349 //----------------------------------------------------------------------------- 350 351 BOOL _CURVECLASS WINAPI SetInRange( long &aValue, long aBorder1, long aBorder2 ) 352 { 353 if ( aBorder1 < aBorder2 ) 354 { 355 if ( aValue < aBorder1 ) 356 { 357 aValue= aBorder1; 358 return FALSE; 359 }; 360 if ( aValue > aBorder2 ) 361 { 362 aValue= aBorder2; 363 return FALSE; 364 }; 365 } 366 else 367 { 368 if ( aValue > aBorder1 ) 369 { 370 aValue= aBorder1; 371 return FALSE; 372 }; 373 if (aValue < aBorder2) 374 { 375 aValue= aBorder2; 376 return FALSE; 377 }; 378 }; 379 return TRUE; 380 } 381 382 /* 383 int _CURVECLASS WINAPI maxi(int value1, int value2) { 384 return ( (value1 > value2) ? value1 : value2); 385 }; 386 387 int _CURVECLASS WINAPI mini(int value1, int value2) { 388 return ( (value1 < value2) ? value1 : value2); 389 }; 390 391 long _CURVECLASS WINAPI maxl(long value1, long value2) { 392 return ( (value1 > value2) ? value1 : value2); 393 }; 394 395 long _CURVECLASS WINAPI minl(long value1, long value2) { 396 return ( (value1 < value2) ? value1 : value2); 397 }; 398 399 float _CURVECLASS WINAPI maxf(float value1, float value2) { 400 return ( (value1 > value2) ? value1 : value2); 401 }; 402 403 float _CURVECLASS WINAPI minf(float value1, float value2) { 404 return ( (value1 < value2) ? value1 : value2); 405 }; 406 407 double _CURVECLASS WINAPI maxd(double value1, double value2) { 408 return ( (value1 > value2) ? value1 : value2); 409 }; 410 411 double _CURVECLASS WINAPI mind(double value1, double value2) { 412 return ( (value1 < value2) ? value1 : value2); 413 };*/ 414