00001 //--------------------------------------------------------------------------- 00002 // 00003 // File: TxqFloatingDecimal.h 00004 // 00005 // Purpose: Determines the exponent and digits of a double 00006 // 00007 // Version: $Id: TxqFloatingDecimal.h,v 1.6 2001/10/12 18:51:23 kgl Exp $ 00008 // 00009 // This class name comes from the FloatingDecimal.java class 00010 // 00011 //--------------------------------------------------------------------------- 00012 00013 #ifndef TXQ_FLOATINGDECIMAL_H 00014 #define TXQ_FLOATINGDECIMAL_H 00015 00016 // system includes 00017 #include <cmath> 00018 #if defined(_MSC_VER) 00019 #include <cfloat> 00020 #else 00021 #include <float.h> 00022 #endif 00023 00024 // txmath includes 00025 #include <TxThroughStream.h> 00026 00027 // Qt includes 00028 #include <qstring.h> 00029 00044 class TxqFloatingDecimal 00045 { 00046 00047 public: 00048 00053 TxqFloatingDecimal(double num) { 00054 if (num < 0.0 ) sign =-1; 00055 else sign = 1; 00056 number = fabs(num); 00057 numDigits=3; 00058 reformat(); 00059 } 00060 00067 TxqFloatingDecimal(double num, int digits) { 00068 if (num < 0.0 ) sign =-1; 00069 else sign = 1; 00070 number = fabs(num); 00071 numDigits=digits; 00072 reformat(); 00073 } 00074 00079 TxqFloatingDecimal(float num) { 00080 TxqFloatingDecimal((double) num); 00081 } 00082 00087 int getSign() { 00088 return sign; 00089 } 00090 00096 int getExponentSign() { 00097 if ( (number < 1.0) && (number != 0) ) return -1; 00098 if (number >= 10.0) return 1; 00099 else return 0; 00100 } 00101 00106 int getExponent() { 00107 return abs(exponent); 00108 } 00109 00116 QString getStringDigits() { 00117 return stringNumber; 00118 } 00119 00124 int getDigit() { 00125 int inum; 00126 if (stringNumber[stringIndex].isDigit()){ 00127 inum = stringNumber[stringIndex].digitValue(); 00128 stringIndex++; 00129 } 00130 else inum = 0; 00131 return inum; 00132 } 00133 00138 double getNumber() { 00139 return number; 00140 } 00141 00145 void setNumDigits(int n) { 00146 numDigits=n; 00147 reformat(); 00148 } 00149 00154 bool isNegative() { 00155 if (getSign() == -1) return true; 00156 else return false; 00157 } 00158 00164 bool isExceptional() { 00165 if ( ( (number < DBL_MIN) && (number < 0) ) 00166 || (number > DBL_MAX) ) return true; 00167 else return false; 00168 } 00169 00173 ~TxqFloatingDecimal(){} 00174 00175 private: 00176 00186 void reformat() { 00187 00188 // always use + number 00189 double a = fabs(number); 00190 stringIndex = 0; 00191 00192 // if the number is 0: 00193 if (a == 0.0) { 00194 exponent = 0; 00195 reformNumber = 1; 00196 digitNumber = a; 00197 stringNumber = "0"; 00198 for (int i=1; i<=numDigits; i++) 00199 stringNumber = stringNumber + "0"; 00200 return; 00201 } 00202 00203 // compute the sign of the exponent 00204 // (this is not good to use as the exponent 00205 // because of round-off errors) 00206 if (a < DBL_MIN) a = DBL_MIN; 00207 double dexponent = (log10(a)); 00208 posExp=true; 00209 if (dexponent < 0.0 ) posExp=false; 00210 00211 // temps contains the number as a string 00212 // with digits, decimal point 00213 // and possibly exponent (e) 00214 QString snumber; 00215 QString temps = snumber.number(a, 'g', numDigits); 00216 00217 // determine if exponent (e) is in the string 00218 // this will be true if the number is below the precision 00219 // (numDigits) 00220 // from QString.number 00221 // if e is not in the string, then must determine the exponent 00222 // by counting 00223 00224 bool countE = true; 00225 if ( temps.contains("e") ) { 00226 countE = false; 00227 } 00228 00229 // if positive exponent, 00230 // and need to count the decimal places, then 00231 // start at -1 00232 // else start at 0 00233 00234 int i=0; 00235 if (posExp) exponent=-1; 00236 else exponent = 0; 00237 pastDecimal=false; 00238 pastFirstDecimal=false; 00239 00240 // loop through all items in the temps string 00241 // break the while loop by setting i outside of the 00242 // temps range 00243 00244 while(!temps[i].isNull()) { 00245 00246 // get the exponent if "e" is present 00247 // at the correct location 00248 QChar e = temps[i]; 00249 if (e == "e") { 00250 // next is sign 00251 i++; 00252 // beginning of exponent 00253 i++; 00254 QString sExp; 00255 while(!temps[i].isNull()) { 00256 if(temps[i].isDigit()) sExp = sExp + temps[i]; 00257 i++; 00258 } 00259 exponent = sExp.toInt(); 00260 i=temps.length()+1; 00261 } 00262 00263 else { 00264 00265 // must count for exponent number 00266 // positve exponent 00267 if (countE) { 00268 if (posExp) { 00269 QChar anum = temps[i]; 00270 00271 // search for decimal point 00272 if (anum == ".") { 00273 i++; 00274 anum = temps[i]; 00275 pastDecimal = true; 00276 } 00277 00278 // increment exponent if not past decimal point 00279 if(anum.isDigit()) { 00280 stringNumber = stringNumber + anum; 00281 if(!pastDecimal) exponent++; 00282 } 00283 else { 00284 i=temps.length()+1; 00285 } 00286 } 00287 00288 // negative exponent 00289 else { 00290 QChar anum = temps[i]; 00291 if (anum == ".") { 00292 i++; 00293 anum = temps[i]; 00294 pastDecimal = true; 00295 } 00296 if (pastDecimal && !pastFirstDecimal) { 00297 if (!temps[i].isNull()) exponent--; 00298 } 00299 if (anum != "0") { 00300 if(anum.isDigit()) stringNumber = stringNumber + anum; 00301 pastFirstDecimal = true; 00302 } 00303 else if (pastFirstDecimal) { 00304 if(anum.isDigit()) stringNumber = stringNumber + anum; 00305 } 00306 } 00307 } 00308 00309 // "e" is not present yet, but not counting for the exponent value 00310 // if the character is a number, add it to the stringNumber 00311 00312 else { 00313 if(temps[i].isDigit()) stringNumber = stringNumber + temps[i]; 00314 } 00315 i++; 00316 } 00317 } 00318 } 00319 00320 /* 00321 * Class data members. 00322 */ 00326 double reformNumber; 00327 00331 double digitNumber; 00332 00336 QString stringNumber; 00337 00341 int stringIndex; 00342 00346 int exponent; 00347 00351 double number; 00352 00356 int sign; 00357 00361 int numDigits; 00362 00366 bool pastDecimal; 00367 00371 bool pastFirstDecimal; 00372 00376 bool posExp; 00377 00378 }; 00379 #endif
Copyright Tech-X Corporation, all rights reserved.