C-XSC - A C++ Class Library for Extended Scientific Computing  2.5.4
dotio.cpp
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