C-XSC - A C++ Class Library for Extended Scientific Computing
2.5.4
|
00001 /* 00002 ** CXSC is a C++ library for eXtended Scientific Computing (V 2.5.4) 00003 ** 00004 ** Copyright (C) 1990-2000 Institut fuer Angewandte Mathematik, 00005 ** Universitaet Karlsruhe, Germany 00006 ** (C) 2000-2014 Wiss. Rechnen/Softwaretechnologie 00007 ** Universitaet Wuppertal, Germany 00008 ** 00009 ** This library is free software; you can redistribute it and/or 00010 ** modify it under the terms of the GNU Library General Public 00011 ** License as published by the Free Software Foundation; either 00012 ** version 2 of the License, or (at your option) any later version. 00013 ** 00014 ** This library is distributed in the hope that it will be useful, 00015 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 ** Library General Public License for more details. 00018 ** 00019 ** You should have received a copy of the GNU Library General Public 00020 ** License along with this library; if not, write to the Free 00021 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 00024 /* CVS $Id: dotio.cpp,v 1.29 2014/01/30 17:23:45 cxsc Exp $ */ 00025 00026 #include <iostream> 00027 #include <string> 00028 #include <cstring> 00029 00030 #include "dot.hpp" 00031 #include "ioflags.hpp" 00032 #include "RtsFunc.h" 00033 00034 #include "dot_defs.hpp" 00035 00036 namespace cxsc { 00037 00038 // #include "dot_defs.hpp" 00039 00040 00041 int d_init_dm (void); 00042 void d_outp(char *buffer, Dotprecision c, 00043 int FormatFlag, int FracDigits, int rnd, 00044 int *length); 00045 00046 #if _WIN32 00047 extern __declspec(thread) char *dm; 00048 #elif __APPLE__ && !CXSC_FORCE_TLS 00049 extern char *dm; 00050 #else 00051 extern __thread char *dm; 00052 #endif 00053 00054 00055 std::string & operator <<(std::string & s,const dotprecision &a) throw() 00056 { 00057 if(ioflags.isset(IOFlags::realformat)) 00058 { 00059 //char *sh = new char[1024]; 00060 string sh; 00061 real rl,ru; 00062 rnd (a, rl, ru); // Bem.: In rnd wird (*this) ggfl. entfernt 00063 00064 sh="dot("; sh << SaveOpt << RndDown; 00065 /*sh << rl;*/ sh+=", "; sh << RndUp; 00066 /*sh<< ru;*/ sh+=")"; sh << RestoreOpt; 00067 s+=sh; 00068 // delete [] sh; 00069 } else 00070 { 00071 rndtype rnd; 00072 int formatflag, addblanks, digits=dotdigits; 00073 int length; 00074 char *str; 00075 if (d_init_dm () == -1) 00076 { 00077 // THROW! 00078 return s; 00079 //errmon (ERR_ALL(NOMOREMEMORY)); 00080 //errmon (ERR_ALL(NOCONTINUEPOSSIBLE)); 00081 } 00082 00083 if (ioflags.isset(IOFlags::rndup)) rnd = RND_UP; 00084 else if (ioflags.isset(IOFlags::rnddown)) rnd = RND_DOWN; 00085 else rnd = RND_NEXT; 00086 00087 if (ioflags.isset(IOFlags::variable)) 00088 formatflag = dotwidth; 00089 else if (ioflags.isset(IOFlags::varfixwidth)) 00090 formatflag = dotwidth, digits = -digits; 00091 else 00092 formatflag = (ioflags.isset(IOFlags::fixed)) ? 0 : -1; 00093 00094 d_outp (str = dm, a.akku, formatflag, digits, rnd, &length); 00095 if (*str == '+') 00096 { 00097 if (ioflags.isset(IOFlags::blank)) *str = ' '; 00098 else if (ioflags.isset(IOFlags::noblank)) str++,length--; 00099 } 00100 addblanks = (length < dotwidth) ? dotwidth - length : 0; 00101 if (ioflags.isset(IOFlags::rightjust)) 00102 { 00103 for (;addblanks; addblanks--) s+= ' '; 00104 } 00105 s+=str; 00106 if (!ioflags.isset(IOFlags::rightjust)) 00107 for (;addblanks; addblanks--) s+= ' '; 00108 00109 } 00110 return s; 00111 } 00112 00113 std::ostream & operator <<(std::ostream & s,const dotprecision &a) throw() 00114 { 00115 string str=""; 00116 str << a; 00117 s << str; 00118 return s; 00119 } 00120 00121 std::string & operator >>(std::string & s,dotprecision &a) throw() 00122 { 00123 rndtype rnd; 00124 a_intg rndfl; 00125 00126 if (ioflags.isset(IOFlags::rndup)) 00127 rnd = RND_UP; 00128 else if (ioflags.isset(IOFlags::rnddown)) 00129 rnd = RND_DOWN; 00130 else rnd = RND_NEXT; 00131 00132 if (d_init_dm () == -1) 00133 { 00134 // throw! 00135 //errmon (ERR_ALL(NOMOREMEMORY)); 00136 //errmon (ERR_ALL(NOCONTINUEPOSSIBLE)); 00137 } 00138 00139 a= 0.0; // AW! wg. Initialisierungsprobleme 00140 00141 strcpy(dm,s.c_str()); 00142 00143 s = cxsc::d_scanp (a.akku,dm, rnd, &rndfl); 00144 if (rndfl) 00145 ScanDotRndFlag = true; 00146 00147 return s; 00148 } 00149 void operator >>(const std::string &s,dotprecision &a) throw() 00150 { 00151 string s2(s); 00152 s2 >> a; 00153 } 00154 void operator >>(const char *s,dotprecision &a) throw() 00155 { 00156 string s2(s); 00157 s2 >> a; 00158 } 00159 00160 std::istream & operator >>(std::istream & s,dotprecision &a) throw() 00161 { 00162 char c; 00163 string d=""; 00164 00165 skipeolnflag = inpdotflag = true; 00166 00167 /* - skip white spaces ----------------------------------- */ 00168 c = skipwhitespaces (s); 00169 00170 /* - get sign and skip following white spaces ------------ */ 00171 if (c == '+' || c == '-') 00172 { 00173 d+=c; 00174 c = skipwhitespaces (s); 00175 } 00176 /* - skip leading zeros -------------------------------- */ 00177 if (c == '0') 00178 c = skipleadingchars (s, '0', '0'); 00179 00180 /* - get digits of integer part ----------------------- */ 00181 do { 00182 if (c >= '0' && c <= '9') 00183 d+= c; 00184 else 00185 break; 00186 00187 if (s.good()) 00188 s.get(c); 00189 else 00190 inpdotflag = false, 00191 c = '\0'; 00192 00193 } while (s.good()); 00194 00195 /* - get point --------------------------------------- */ 00196 if (c == '.') 00197 { 00198 d+= '.'; 00199 if (s.good()) 00200 s.get(c); 00201 else 00202 inpdotflag = false, 00203 c = '\0'; 00204 } 00205 /* - get digits of fractional part ------------------- */ 00206 do { 00207 if (c >= '0' && c <= '9') 00208 d+= c; 00209 else 00210 break; 00211 00212 if (s.good()) 00213 s.get(c); 00214 else 00215 inpdotflag = false, 00216 c = '\0'; 00217 00218 } while (s.good()); 00219 00220 /* - get Exponent ------------------------------------ */ 00221 if (c == 'E' || c == 'e') 00222 { 00223 d+= c; 00224 if (s.good()) 00225 s.get(c); 00226 else inpdotflag = false, 00227 c = '\0'; 00228 00229 /* - get sign of Exponent -------------------------- */ 00230 if (c == '+' || c == '-') 00231 { 00232 d+= c; 00233 if (s.good()) 00234 s.get(c); 00235 else 00236 inpdotflag = false, 00237 c = '\0'; 00238 } 00239 00240 /* - get Exponent digits --------------------------- */ 00241 do { 00242 if (c >= '0' && c <= '9') 00243 d+= c; 00244 else 00245 break; 00246 00247 if (s.good()) 00248 s.get(c); 00249 else 00250 inpdotflag = false, 00251 c = '\0'; 00252 00253 } while (s.good()); 00254 } 00255 00256 /* Fehler auf zu langen Inputstring pruefen ---- mr???? */ 00257 // Braucht bei Strings nicht mehr beruecksichtigt werden 00258 00259 // -------------------------------------------------------------- 00260 // mindestens 1 Trennzeichen wird gefordert und uebergangen 00261 waseolnflag = (c == '\n'); 00262 00263 // -------------------------------------------------------------- 00264 // erzeugten String scannen 00265 00266 d>>a; 00267 00268 return s; 00269 } 00270 } // namespace cxsc 00271 00272 /****************************************************************/ 00273 /* */ 00274 /* Filename : d_outp.c */ 00275 /* */ 00276 /* Entries : void d_out */ 00277 /* (buffer,c,FormatFlag,FracDigits, */ 00278 /* rnd,length) */ 00279 /* char *buffer; */ 00280 /* dotprecision c; */ 00281 /* a_intg FormatFlag,FracDigits,rnd; */ 00282 /* a_intg *length */ 00283 /* */ 00284 /* Arguments : */ 00285 /* buffer - output string */ 00286 /* c - accu for output */ 00287 /* FormatFlag - format selection */ 00288 /* -1 = scientific format */ 00289 /* 0 = fixed format */ 00290 /* > 0 = variable format */ 00291 /* value is the total field */ 00292 /* width */ 00293 /* FracDigits - number of fraction digits*/ 00294 /* rnd - rounding monde (-1,0,1) */ 00295 /* length - size of buffer string */ 00296 /* */ 00297 /* */ 00298 /* Description : Decimal representation determined from*/ 00299 /* dotprecision akku */ 00300 /* */ 00301 /* External : */ 00302 /* d_out - conversion of akku */ 00303 /* */ 00304 /* Globals : dm - I/O-buffer */ 00305 /* */ 00306 /* Author : M.Rauch */ 00307 /* Date : 1990-09-30 */ 00308 /* */ 00309 /****************************************************************/ 00310 00311 00312 00313 #include "dot_defs.hpp" 00314 #include <stdlib.h> 00315 00316 namespace cxsc { 00317 00318 /* ---------------------------------------------------------------- */ 00319 /* ---------------------------------------------------------------- */ 00320 /* Stringbreich zur Aufnahme eines Akku */ 00321 00322 /* char dm[A_DIGITS]; */ 00323 #if _WIN32 00324 __declspec(thread) char *dm = NULL; 00325 __declspec(thread) char *dmhlp = NULL; 00326 #elif __APPLE__ && !CXSC_FORCE_TLS 00327 char *dm = NULL; 00328 char *dmhlp = NULL; 00329 #else 00330 __thread char *dm = NULL; 00331 __thread char *dmhlp = NULL; 00332 #endif 00333 00334 /* ---------------------------------------------------------------- */ 00335 00336 int d_init_dm(void) 00337 { 00338 00339 if (dm) 00340 return 1; 00341 00342 dmhlp = (char*) malloc (A_DIGITS); 00343 dm = (char*) malloc (A_DIGITS); 00344 00345 return (dm && dmhlp) ? 0 : -1; 00346 } 00347 00348 /* ---------------------------------------------------------------- */ 00349 00350 void d_outp(char *buffer, Dotprecision c, 00351 int FormatFlag, int FracDigits, int rnd, 00352 int *length) 00353 00354 { 00355 a_intg dexpo,bdp,len; 00356 a_intg expo,i,digits,IntDigits,DecPlaces,vz; 00357 a_intg HoldWidth = (FracDigits < 0); 00358 char *s,*p; 00359 00360 #if TEST 00361 printf("d_outp\n"); 00362 #endif 00363 00364 if (HoldWidth) FracDigits = -FracDigits; 00365 00366 /* */ 00367 /* Kehre n�tigenfalls Rundungsrichtung um */ 00368 /* */ 00369 00370 if ((vz = (a_intg)c[A_SIGN]) != 0) { 00371 rnd = -rnd; 00372 } 00373 00374 bdp = 2+A_I_DIGITS; 00375 len = bdp+1; 00376 if (c[A_END] > A_D_P) len += B_LENGTH * ((a_intg)c[A_END] - A_D_P); 00377 00378 d_out (&dexpo, dm, &bdp, &len, c); 00379 dm[len] = '0'; 00380 00381 /* */ 00382 /* floating-point reprensentation */ 00383 /* */ 00384 00385 /* erzwinge n�tigenfalls Gleitkommadarstellung */ 00386 00387 if (FormatFlag > 0 && FormatFlag-FracDigits <= 2) { 00388 FormatFlag = FracDigits+3; 00389 } 00390 if (FormatFlag > 0) { 00391 if (dexpo < -((FracDigits+1)/2) || 00392 (dexpo > 0 && dexpo >= FormatFlag-FracDigits-2)) { 00393 FormatFlag = -1; 00394 if (HoldWidth) { 00395 FracDigits = (FracDigits < 6) ? 0 : FracDigits-6; 00396 } 00397 } 00398 } 00399 00400 if (FormatFlag == -1) 00401 { 00402 DecPlaces = FracDigits; 00403 digits = (len - bdp - 1) + (dexpo + 1); 00404 if (digits < DecPlaces) DecPlaces = digits-1; 00405 00406 b_rnd (rnd, dm, digits+1, DecPlaces+1, &bdp, &dexpo); 00407 00408 p = buffer; 00409 *p++ = (vz) ? '-' : '+'; /* Vorzeichen */ 00410 s = &dm[bdp-dexpo]; 00411 *p++ = *s++; /* Digit vor Dezimalpunkt */ 00412 if (FracDigits) { 00413 *p++ = '.'; /* Dezimalpunkt */ 00414 for (i=0;i<DecPlaces;i++) *p++ = *s++; /* Nachkommadigits */ 00415 for (;i<FracDigits;i++) *p++ = '0'; /* Nachkommadigits mit '0' */ 00416 } 00417 *p++ = 'E'; /* Exponentzeichen 'E' */ 00418 *p++ = (dexpo<0) ? '-' : '+'; /* Vorzeichen Exponent */ 00419 expo = (dexpo<0) ? -dexpo : dexpo; 00420 for (i=A_E_DIGITS-1; i >= 0; i--) { /* Exponent */ 00421 p[i] = expo%10 + '0'; 00422 expo /= 10; 00423 } 00424 *length = 3+FracDigits+2+A_E_DIGITS; 00425 } 00426 00427 /* */ 00428 /* fixed-point reprensentation */ 00429 /* */ 00430 00431 else 00432 { 00433 DecPlaces = (FracDigits < (len-bdp-1)) ? FracDigits : (len-bdp-1); 00434 if (dexpo >= 0) { 00435 IntDigits = dexpo+1; 00436 } 00437 else { 00438 IntDigits = 1; 00439 for (i=0; i < -dexpo; i++) dm[bdp+i] = '0'; 00440 dexpo = 0; 00441 } 00442 digits = (len - bdp - 1) + (dexpo + 1); 00443 00444 b_rnd (rnd, dm, digits+1, IntDigits+DecPlaces, &bdp, &dexpo); 00445 00446 p = buffer; 00447 *p++ = (vz) ? '-' : '+'; /* Vorzeichen */ 00448 s = &dm[bdp-IntDigits+1]; 00449 for(i=0;i<IntDigits;i++) *p++ = *s++; /* Digits vor Dezimalpunkt */ 00450 if (FracDigits) { 00451 *p++ = '.'; /* Dezimalpunkt */ 00452 for (i=0;i<DecPlaces;i++) *p++ = *s++; /* Nachkommadigits */ 00453 for (;i<FracDigits;i++) *p++ = '0'; /* Nachkommadigits mit 0 */ 00454 } 00455 *length = IntDigits+FracDigits+2; 00456 } 00457 if (FracDigits == 0) (*length)--; 00458 buffer[*length] = '\0'; 00459 } 00460 00461 /****************************************************************/ 00462 /* */ 00463 /* Filename : d_out.c */ 00464 /* */ 00465 /* Entries : void d_out */ 00466 /* (dexpo,buffer,bdp,len,c) 4 */ 00467 /* a_intg *dexpo,*bdp,*len; */ 00468 /* char *buffer; */ 00469 /* dotprecision c; */ 00470 /* */ 00471 /* Arguments : */ 00472 /* dexpo - decimal exponent of first */ 00473 /* digit */ 00474 /* buffer - output string */ 00475 /* bdp - position of decimal point */ 00476 /* len - input: usable size of buffer */ 00477 /* output: totaly produced digits */ 00478 /* c - accu for output */ 00479 /* */ 00480 /* */ 00481 /* Description : Decimal representation determined from*/ 00482 /* dotprecision akku */ 00483 /* */ 00484 /* External : */ 00485 /* b_outf - conversion of fractional part*/ 00486 /* b_outi - conversion of integer part */ 00487 /* */ 00488 /* Globals : b_cm__ - I/O-buffer */ 00489 /* */ 00490 /* Author : M.Rauch */ 00491 /* Date : 1990-09-30 */ 00492 /****************************************************************/ 00493 00494 } 00495 // #include "o_defs.h" 00496 #if WINDOWS_X86_32 00497 #include "dot.hpp" 00498 Dotprecision b_cm__; 00499 #else 00500 extern Dotprecision b_cm__; 00501 #endif 00502 00503 namespace cxsc { 00504 void d_out(a_intg *dexpo, char *buffer, a_intg *bdp, a_intg *len, 00505 Dotprecision c) 00506 00507 { 00508 a_intg i,digits,cont; 00509 00510 #if TEST 00511 printf("d_out\n"); 00512 #endif 00513 00514 /* copy akku c to temporary akku b_cm__ */ 00515 00516 b_cm__[A_BEGIN] = c[A_BEGIN]; 00517 b_cm__[A_END] = c[A_END]; 00518 for (i=(a_intg)c[A_BEGIN]; i <= (a_intg)c[A_END]; i++) 00519 b_cm__[i] = c[i]; 00520 00521 /* test if akku is zero */ 00522 00523 if (b_cm__[A_BEGIN]==ZERO || b_cm__[A_END]==ZERO || b_cm__[A_BEGIN]>b_cm__[A_END]) { 00524 buffer[*bdp] = '0'; 00525 for (i=*bdp+1; i < *len; i++) buffer[i] = '0'; 00526 *dexpo = 0; 00527 return; 00528 } 00529 00530 /* clear accu contents between number and decimal point */ 00531 for (i=(a_intg)b_cm__[A_END]+1; i <= A_D_P; i++) 00532 b_cm__[i] = ZERO; 00533 for (i=A_D_P+1; i < (a_intg)b_cm__[A_BEGIN]; i++) 00534 b_cm__[i] = ZERO; 00535 00536 /* */ 00537 /* conversion of integer part */ 00538 /* */ 00539 00540 *dexpo = -1; 00541 if (b_cm__[A_BEGIN] <= A_D_P) { 00542 digits = *len; 00543 b_outi(&digits,buffer,bdp,dexpo,b_cm__); 00544 } 00545 00546 /* */ 00547 /* conversion of fraction part */ 00548 /* */ 00549 00550 digits = (*len < *bdp+1) ? 0 : *len - *bdp - 1; 00551 if (digits>0) { 00552 cont = 0; 00553 b_outf(&digits,buffer,bdp,&cont,b_cm__); 00554 if (*dexpo < 0) { 00555 for (cont=*bdp+1; cont < *len-1; cont++) { 00556 if (buffer[cont] != '0') break; 00557 (*dexpo)--; 00558 } 00559 } 00560 } 00561 00562 return; 00563 } 00564 00565 /****************************************************************/ 00566 /* */ 00567 /* Filename : d_scanp.c */ 00568 /* */ 00569 /* Entries : char* d_scanp (c,inpbuf,rnd,rndfl) */ 00570 /* dotprecision c; */ 00571 /* char *inpbuf; */ 00572 /* a_intg rnd,*rndfl; */ 00573 /* */ 00574 /* Arguments : */ 00575 /* c - accu holding IEEE value */ 00576 /* inpbuf - buffer with input digits */ 00577 /* rnd - direction of rounding */ 00578 /* rndfl - flag 'rounding occurred' */ 00579 /* */ 00580 /* Description : Convert a character string */ 00581 /* to the corresponding IEEE value */ 00582 /* */ 00583 /* Author : M.Rauch, University of Karlsruhe */ 00584 /* Date : 1990-10-20 */ 00585 /****************************************************************/ 00586 00587 00588 char* d_scanp(Dotprecision c, char *inpbuf, a_intg rnd, a_intg *rndfl) 00589 { 00590 char *s; 00591 a_intg sign, dexpo, bdp, len; 00592 a_btyp *p,*pe; 00593 /* */ 00594 /* convert input string into a convertible form */ 00595 /* */ 00596 00597 s = d_scan (inpbuf, &sign, &dexpo, dm, &bdp, &len); 00598 00599 /* */ 00600 /* change rnd-direction if input string is negativ */ 00601 /* */ 00602 00603 c[A_SIGN] = sign; 00604 if (sign && rnd) 00605 rnd = -rnd; 00606 00607 /* */ 00608 /* convert integer and fractional parts */ 00609 /* */ 00610 00611 d_scani (c, dm, &dexpo, &bdp, &len); 00612 *rndfl = d_scanf (c, dm, &dexpo, &bdp, &len, rnd); 00613 00614 /* */ 00615 /* adjust akku and test if akku is ZERO */ 00616 /* */ 00617 00618 for (p=&c[(a_intg)c[A_BEGIN]],pe=&c[(a_intg)c[A_END]]; p <= pe; p++) 00619 { 00620 if (*p != ZERO) 00621 break; 00622 c[A_BEGIN]++; 00623 } 00624 for (; pe >= p; pe--) 00625 { 00626 if (*pe != ZERO) 00627 break; 00628 c[A_END]--; 00629 } 00630 if (p > pe) 00631 { 00632 c[A_BEGIN] = c[A_END] = 0; 00633 } 00634 00635 c[A_STATUS] |= A_PZERO+A_MZERO; 00636 return s; 00637 } 00638 00639 /****************************************************************/ 00640 /* */ 00641 /* Filename : d_scani.c */ 00642 /* */ 00643 /* Entries : d_scani (c, buffer, dexpo, bdp, len) */ 00644 /* Dotprecision c; */ 00645 /* char *buffer; */ 00646 /* int *dexpo,*bdp,*len; */ 00647 /* */ 00648 /* Arguments : */ 00649 /* c - accu holding IEEE value */ 00650 /* buffer - buffer with input digits */ 00651 /* bdp - position of decimal point */ 00652 /* dexpo - exponent of first non-zero */ 00653 /* digit */ 00654 /* len - position behind last input digit*/ 00655 /* */ 00656 /* Description : Convert a character string */ 00657 /* to the integer part of IEEE value */ 00658 /* */ 00659 /* Author : M.Rauch, University of Karlsruhe */ 00660 /* Date : 1990-10-19 */ 00661 /****************************************************************/ 00662 00663 00664 void d_scani(Dotprecision c, char *buffer, a_intg *dexpo, 00665 a_intg *bdp, a_intg *len) 00666 00667 { 00668 a_intg i,j; 00669 a_btyp carry; 00670 a_btyp *s,*p,h,hh; 00671 char *q,*qe; 00672 00673 /* */ 00674 /* initialize */ 00675 /* */ 00676 c[A_BEGIN] = c[A_END] = A_D_P, 00677 c[A_D_P] = ZERO; 00678 if (*dexpo < 0) 00679 return; 00680 00681 i = (*dexpo+1) % B2D_LOG10; 00682 if (i) 00683 { 00684 q = buffer + *bdp - *dexpo - 1; 00685 for (; i < B2D_LOG10; i++,(*dexpo)++,q--) 00686 *q = '0'; 00687 } 00688 for (i=*len; i <= *bdp; i++) 00689 buffer[i] = '0'; 00690 00691 q = buffer + *bdp - *dexpo; 00692 qe = buffer + *bdp; 00693 s = &c[(a_intg)c[A_BEGIN]]; 00694 00695 /* */ 00696 /* convert by repeated multiplication */ 00697 /* */ 00698 00699 while (q < qe) 00700 { 00701 /* get decimal digits */ 00702 for (j=0,i=B2D_LOG10;i>0;i--,q++) 00703 { 00704 /* carry = 10*carry + *q - '0'; */ 00705 j = j*10 + *q - '0'; 00706 } 00707 carry = j; 00708 00709 for (p=&c[A_D_P]; p >= s; p--) 00710 { 00711 hh = GETLOW(*p)*B2D_POWER+carry, 00712 h = GETHIGH(*p)*B2D_POWER+GETHIGH(hh), 00713 carry = GETHIGH(h), 00714 *p = MOVEHIGH(h) | GETLOW(hh); 00715 } 00716 00717 /* adjust digits */ 00718 if (carry) 00719 { 00720 c[A_BEGIN]--, s--; 00721 *s = carry; 00722 } 00723 00724 } 00725 return; 00726 } 00727 00728 /****************************************************************/ 00729 /* */ 00730 /* Filename : d_scanf.c */ 00731 /* */ 00732 /* Entries : a_intg d_scanf (c,buffer,dexpo,bdp,len,rnd) */ 00733 /* Dotprecision c; */ 00734 /* char *buffer; */ 00735 /* a_intg *dexpo,*bdp,*len,rnd; */ 00736 /* */ 00737 /* Arguments : */ 00738 /* c - accu holding IEEE value */ 00739 /* buffer - buffer with input digits */ 00740 /* bdp - position of decimal point */ 00741 /* dexpo - exponent of first non-zero */ 00742 /* digit */ 00743 /* len - position behind last input digit*/ 00744 /* rnd - direction of rounding */ 00745 /* */ 00746 /* Description : Convert a character string */ 00747 /* to the fractional part of IEEE value */ 00748 /* */ 00749 /* Author : M.Rauch, University of Karlsruhe */ 00750 /* Date : 1990-10-19 */ 00751 /****************************************************************/ 00752 00753 00754 a_intg d_scanf(Dotprecision c, char *buffer, a_intg *dexpo, 00755 a_intg *bdp, a_intg *len, a_intg rnd) 00756 00757 { 00758 a_intg i,j,rndflag = 0; 00759 a_btyp mod, carry; 00760 a_btyp *s,*p,*pe,h,hh; 00761 char *q,*qe; 00762 00763 00764 /* */ 00765 /* initialize */ 00766 /* */ 00767 00768 if (*len+1 <= *bdp) 00769 return rndflag; 00770 00771 for (i=*bdp-*dexpo; *dexpo < 0; (*dexpo)++,i--) 00772 buffer[i] = '0'; 00773 00774 i = (*len - *bdp - 1) % B2D_LOG10; 00775 if (i) 00776 { 00777 q = buffer + *len; 00778 for (; i < B2D_LOG10; i++,(*len)++,q++) 00779 *q = '0'; 00780 } 00781 00782 qe = buffer + *bdp + 1; 00783 q = buffer + *len; 00784 s = &c[(a_intg)c[A_END]]; 00785 00786 /* */ 00787 /* convert by repeated division */ 00788 /* */ 00789 00790 carry = 0; 00791 while (q > qe) 00792 { 00793 /* get decimal digits */ 00794 for (q-=B2D_LOG10,j=i=0;i<B2D_LOG10;i++) 00795 { 00796 /* mod = 10*mod + q[i] - '0'; */ 00797 j = j*10 + q[i] - '0'; 00798 } 00799 mod = j + carry; 00800 if (mod == B2D_POWER) 00801 { 00802 carry = 1, mod = 0; 00803 } else 00804 carry = 0; 00805 00806 p=&c[A_D_P+1]; 00807 00808 do { 00809 for (;p<=s;p++) 00810 { 00811 h = GETHIGH(*p) | MOVEHIGH(mod), 00812 hh = GETLOW(*p) | MOVEHIGH(h%B2D_POWER), 00813 mod = hh%B2D_POWER, 00814 *p = MOVEHIGH(h/B2D_POWER) | (hh/B2D_POWER); 00815 } 00816 if (mod && c[A_END] < A_LENGTH-1) 00817 { 00818 c[A_END]++, s++; 00819 *s = ZERO; 00820 } 00821 } while (p <= s); 00822 00823 if (mod) 00824 rndflag = 1; 00825 00826 if (rnd < 0) 00827 mod = 0; 00828 else if (rnd == 0 && mod < B2D_POWER/2) 00829 mod = 0; 00830 00831 if (mod) 00832 { 00833 /* Runden nach oben : c um 1 Inkermentieren */ 00834 00835 p = &c[A_LENGTH-1], /* == s */ 00836 pe = &c[A_D_P+1]; 00837 for(; p >= pe; p--) 00838 { 00839 (*p)++; 00840 if (*p) 00841 break; 00842 } 00843 if (p < pe) 00844 carry = 1; 00845 00846 } 00847 } 00848 00849 if (carry) 00850 { 00851 p = &c[A_D_P]; 00852 pe = &c[(a_intg)c[A_BEGIN]]; 00853 for(; p >= pe; p--) 00854 { 00855 (*p)++; 00856 if (*p) 00857 break; 00858 } 00859 if (p < pe) 00860 { 00861 --c[A_BEGIN]; 00862 *p = 1; 00863 } 00864 } 00865 00866 return rndflag; 00867 } 00868 00869 /****************************************************************/ 00870 /* */ 00871 /* Filename : d_scan.c */ 00872 /* */ 00873 /* Entries : char* d_scan.c */ 00874 /* (inpbuf, sign,dexpo,outbuf,bdp,len) */ 00875 /* a_intg *sign,*dexpo,*bdp,*len; */ 00876 /* char *inpbuf, *outbuf; */ 00877 /* */ 00878 /* Arguments : */ 00879 /* inpbuf - string to scan */ 00880 /* Returnvalues : */ 00881 /* sign - sign flag */ 00882 /* dexpo - decimal exponent of first */ 00883 /* digit */ 00884 /* outbuf - output string */ 00885 /* min.length: A_DIGITS */ 00886 /* bdp - position of decimal point */ 00887 /* len - totaly produced digits */ 00888 /* output: totaly produced digits */ 00889 /* c - accu for output */ 00890 /* */ 00891 /* */ 00892 /* Description : the input string is scanned and */ 00893 /* transferred into an ordered form */ 00894 /* */ 00895 /* Author : M.Rauch */ 00896 /* Date : 1990-10-14 */ 00897 /****************************************************************/ 00898 00899 00900 char* d_scan (char *inpbuf, a_intg *sign, a_intg *dexpo, 00901 char *outbuf, a_intg *bdp, a_intg *len) 00902 00903 { 00904 a_intg start, point, mantend, expo, end; 00905 a_intg digits,fl,i,j; 00906 char c; 00907 00908 /* intialiaze parameters */ 00909 00910 *bdp = 1 + A_I_DIGITS; 00911 *len = (*bdp)+1; 00912 *dexpo = 0; 00913 00914 /* */ 00915 /* determine structure of input string */ 00916 /* */ 00917 00918 fl = 0; 00919 for (start=0; (c = inpbuf[start]) != 0; start++) 00920 { /* skip white spaces */ 00921 if (c > ' ') 00922 break; 00923 } 00924 00925 if (c == '-' || c == '+') /* determine sign */ 00926 *sign = ((c == '-') ? 1 : 0), 00927 start++; 00928 else 00929 *sign = 0; 00930 00931 for (; (c = inpbuf[start]) != 0; start++) 00932 { /* skip white spaces */ 00933 if (c > ' ') 00934 break; 00935 } 00936 for (; (c = inpbuf[start]) != 0; start++) 00937 { /* skip leading zero */ 00938 if (c != '0') 00939 break; 00940 } 00941 00942 for (end=start; (c = inpbuf[end]) != 0; end++) 00943 { /* skip intdigits */ 00944 if (c < '0' || c > '9') 00945 break; 00946 } 00947 if (c == '.') /* pos. of decimalpoint */ 00948 point = end, 00949 end++, 00950 fl++; 00951 else 00952 point = -1; 00953 00954 for (; (c = inpbuf[end]) != 0; end++) 00955 { /* skip fracdigits */ 00956 if (c < '0' || c > '9') 00957 break; 00958 } 00959 mantend = end; /* end of mantissa */ 00960 00961 if (c == 'E' || c == 'e') /* determine exponent */ 00962 { 00963 c = inpbuf[++end]; 00964 if (c == '+' || c == '-') /* sign of exponent */ 00965 expo = ((c == '-') ? 1 : 0), 00966 end++; 00967 else 00968 expo = 0; 00969 for (i=0; (c = inpbuf[end]) != 0; end++) 00970 { /* value of exponent */ 00971 if (c < '0' || c > '9') 00972 break; 00973 if (i >= (A_E_MAX/10)) 00974 { 00975 break; /* Error Exponent To big ---- mr???? */ 00976 } 00977 i = 10*i + c - '0'; 00978 } 00979 expo = expo ? -i : i; 00980 } else 00981 expo = 0; 00982 00983 if (c) 00984 end++; /* skip at least one delimeter char */ 00985 00986 /* */ 00987 /* check if there are some digits in the mantissa */ 00988 /* */ 00989 00990 if (start+fl == mantend) 00991 { 00992 outbuf[*bdp] = '0'; 00993 return &inpbuf[end]; 00994 } 00995 00996 if (point != -1) 00997 { 00998 digits = mantend - start - 1; 00999 *dexpo = (point - start - 1) + expo; 01000 if (start == point) digits++, 01001 (*dexpo)++; 01002 } else 01003 { 01004 digits = mantend - start; 01005 *dexpo = (mantend - start - 1) + expo; 01006 } 01007 01008 if (*dexpo >= (A_I_DIGITS-10)) 01009 { 01010 /* Error Input Value Too big ---- mr ???? */ 01011 } 01012 if (*dexpo <= - (A_F_DIGITS-10)) 01013 { 01014 /* Error Input Value Too small ---- mr ???? */ 01015 } 01016 01017 /* */ 01018 /* take known digits into output string */ 01019 /* */ 01020 01021 *len = *bdp - *dexpo + digits; 01022 if (*len >= A_DIGITS) 01023 { 01024 /* Error Input String Too long ---- mr ???? */ 01025 } 01026 for (j=*len-1,i=mantend-1; i >= start; i--) 01027 { 01028 if ((c = inpbuf[i]) != '.') 01029 outbuf[j--] = c; 01030 } 01031 if (start == point) 01032 outbuf[j] = '0'; 01033 01034 /* */ 01035 /* be shure that the decimal point is in the output string */ 01036 /* */ 01037 01038 if (*dexpo < 0) 01039 { 01040 for (j=-*dexpo,i=*bdp-*dexpo-1; j > 0; j--,i--) 01041 outbuf[i] = '0'; 01042 *dexpo = 0; 01043 } 01044 01045 if (*len <= *bdp) 01046 { 01047 for (j=(*bdp)-(*len)+1,i=*len; j > 0; j--,i++) 01048 outbuf[i] = '0'; 01049 *len = (*bdp)+1; 01050 } 01051 01052 return &inpbuf[end]; 01053 } 01054 01055 } // namespace cxsc 01056