C-XSC - A C++ Class Library for Extended Scientific Computing  2.5.4
dotio.cpp
1 /*
2 ** CXSC is a C++ library for eXtended Scientific Computing (V 2.5.4)
3 **
4 ** Copyright (C) 1990-2000 Institut fuer Angewandte Mathematik,
5 ** Universitaet Karlsruhe, Germany
6 ** (C) 2000-2014 Wiss. Rechnen/Softwaretechnologie
7 ** Universitaet Wuppertal, Germany
8 **
9 ** This library is free software; you can redistribute it and/or
10 ** modify it under the terms of the GNU Library General Public
11 ** License as published by the Free Software Foundation; either
12 ** version 2 of the License, or (at your option) any later version.
13 **
14 ** This library is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 ** Library General Public License for more details.
18 **
19 ** You should have received a copy of the GNU Library General Public
20 ** License along with this library; if not, write to the Free
21 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23 
24 /* CVS $Id: dotio.cpp,v 1.29 2014/01/30 17:23:45 cxsc Exp $ */
25 
26 #include <iostream>
27 #include <string>
28 #include <cstring>
29 
30 #include "dot.hpp"
31 #include "ioflags.hpp"
32 #include "RtsFunc.h"
33 
34 #include "dot_defs.hpp"
35 
36 namespace cxsc {
37 
38 // #include "dot_defs.hpp"
39 
40 
41 int d_init_dm (void);
42 void d_outp(char *buffer, Dotprecision c,
43  int FormatFlag, int FracDigits, int rnd,
44  int *length);
45 
46 #if _WIN32
47 extern __declspec(thread) char *dm;
48 #elif __APPLE__ && !CXSC_FORCE_TLS
49 extern char *dm;
50 #else
51 extern __thread char *dm;
52 #endif
53 
54 
55 std::string & operator <<(std::string & s,const dotprecision &a) throw()
56 {
57  if(ioflags.isset(IOFlags::realformat))
58  {
59  //char *sh = new char[1024];
60  string sh;
61  real rl,ru;
62  rnd (a, rl, ru); // Bem.: In rnd wird (*this) ggfl. entfernt
63 
64  sh="dot("; sh << SaveOpt << RndDown;
65  /*sh << rl;*/ sh+=", "; sh << RndUp;
66  /*sh<< ru;*/ sh+=")"; sh << RestoreOpt;
67  s+=sh;
68  // delete [] sh;
69  } else
70  {
71  rndtype rnd;
72  int formatflag, addblanks, digits=dotdigits;
73  int length;
74  char *str;
75  if (d_init_dm () == -1)
76  {
77  // THROW!
78  return s;
79  //errmon (ERR_ALL(NOMOREMEMORY));
80  //errmon (ERR_ALL(NOCONTINUEPOSSIBLE));
81  }
82 
83  if (ioflags.isset(IOFlags::rndup)) rnd = RND_UP;
84  else if (ioflags.isset(IOFlags::rnddown)) rnd = RND_DOWN;
85  else rnd = RND_NEXT;
86 
87  if (ioflags.isset(IOFlags::variable))
88  formatflag = dotwidth;
89  else if (ioflags.isset(IOFlags::varfixwidth))
90  formatflag = dotwidth, digits = -digits;
91  else
92  formatflag = (ioflags.isset(IOFlags::fixed)) ? 0 : -1;
93 
94  d_outp (str = dm, a.akku, formatflag, digits, rnd, &length);
95  if (*str == '+')
96  {
97  if (ioflags.isset(IOFlags::blank)) *str = ' ';
98  else if (ioflags.isset(IOFlags::noblank)) str++,length--;
99  }
100  addblanks = (length < dotwidth) ? dotwidth - length : 0;
101  if (ioflags.isset(IOFlags::rightjust))
102  {
103  for (;addblanks; addblanks--) s+= ' ';
104  }
105  s+=str;
106  if (!ioflags.isset(IOFlags::rightjust))
107  for (;addblanks; addblanks--) s+= ' ';
108 
109  }
110  return s;
111 }
112 
113 std::ostream & operator <<(std::ostream & s,const dotprecision &a) throw()
114 {
115  string str="";
116  str << a;
117  s << str;
118  return s;
119 }
120 
121 std::string & operator >>(std::string & s,dotprecision &a) throw()
122 {
123  rndtype rnd;
124  a_intg rndfl;
125 
126  if (ioflags.isset(IOFlags::rndup))
127  rnd = RND_UP;
128  else if (ioflags.isset(IOFlags::rnddown))
129  rnd = RND_DOWN;
130  else rnd = RND_NEXT;
131 
132  if (d_init_dm () == -1)
133  {
134  // throw!
135  //errmon (ERR_ALL(NOMOREMEMORY));
136  //errmon (ERR_ALL(NOCONTINUEPOSSIBLE));
137  }
138 
139  a= 0.0; // AW! wg. Initialisierungsprobleme
140 
141  strcpy(dm,s.c_str());
142 
143  s = cxsc::d_scanp (a.akku,dm, rnd, &rndfl);
144  if (rndfl)
145  ScanDotRndFlag = true;
146 
147  return s;
148 }
149 void operator >>(const std::string &s,dotprecision &a) throw()
150 {
151  string s2(s);
152  s2 >> a;
153 }
154 void operator >>(const char *s,dotprecision &a) throw()
155 {
156  string s2(s);
157  s2 >> a;
158 }
159 
160 std::istream & operator >>(std::istream & s,dotprecision &a) throw()
161 {
162  char c;
163  string d="";
164 
165  skipeolnflag = inpdotflag = true;
166 
167  /* - skip white spaces ----------------------------------- */
168  c = skipwhitespaces (s);
169 
170  /* - get sign and skip following white spaces ------------ */
171  if (c == '+' || c == '-')
172  {
173  d+=c;
174  c = skipwhitespaces (s);
175  }
176  /* - skip leading zeros -------------------------------- */
177  if (c == '0')
178  c = skipleadingchars (s, '0', '0');
179 
180  /* - get digits of integer part ----------------------- */
181  do {
182  if (c >= '0' && c <= '9')
183  d+= c;
184  else
185  break;
186 
187  if (s.good())
188  s.get(c);
189  else
190  inpdotflag = false,
191  c = '\0';
192 
193  } while (s.good());
194 
195  /* - get point --------------------------------------- */
196  if (c == '.')
197  {
198  d+= '.';
199  if (s.good())
200  s.get(c);
201  else
202  inpdotflag = false,
203  c = '\0';
204  }
205  /* - get digits of fractional part ------------------- */
206  do {
207  if (c >= '0' && c <= '9')
208  d+= c;
209  else
210  break;
211 
212  if (s.good())
213  s.get(c);
214  else
215  inpdotflag = false,
216  c = '\0';
217 
218  } while (s.good());
219 
220  /* - get Exponent ------------------------------------ */
221  if (c == 'E' || c == 'e')
222  {
223  d+= c;
224  if (s.good())
225  s.get(c);
226  else inpdotflag = false,
227  c = '\0';
228 
229  /* - get sign of Exponent -------------------------- */
230  if (c == '+' || c == '-')
231  {
232  d+= c;
233  if (s.good())
234  s.get(c);
235  else
236  inpdotflag = false,
237  c = '\0';
238  }
239 
240  /* - get Exponent digits --------------------------- */
241  do {
242  if (c >= '0' && c <= '9')
243  d+= c;
244  else
245  break;
246 
247  if (s.good())
248  s.get(c);
249  else
250  inpdotflag = false,
251  c = '\0';
252 
253  } while (s.good());
254  }
255 
256  /* Fehler auf zu langen Inputstring pruefen ---- mr???? */
257  // Braucht bei Strings nicht mehr beruecksichtigt werden
258 
259  // --------------------------------------------------------------
260  // mindestens 1 Trennzeichen wird gefordert und uebergangen
261  waseolnflag = (c == '\n');
262 
263  // --------------------------------------------------------------
264  // erzeugten String scannen
265 
266  d>>a;
267 
268  return s;
269 }
270 } // namespace cxsc
271 
272 /****************************************************************/
273 /* */
274 /* Filename : d_outp.c */
275 /* */
276 /* Entries : void d_out */
277 /* (buffer,c,FormatFlag,FracDigits, */
278 /* rnd,length) */
279 /* char *buffer; */
280 /* dotprecision c; */
281 /* a_intg FormatFlag,FracDigits,rnd; */
282 /* a_intg *length */
283 /* */
284 /* Arguments : */
285 /* buffer - output string */
286 /* c - accu for output */
287 /* FormatFlag - format selection */
288 /* -1 = scientific format */
289 /* 0 = fixed format */
290 /* > 0 = variable format */
291 /* value is the total field */
292 /* width */
293 /* FracDigits - number of fraction digits*/
294 /* rnd - rounding monde (-1,0,1) */
295 /* length - size of buffer string */
296 /* */
297 /* */
298 /* Description : Decimal representation determined from*/
299 /* dotprecision akku */
300 /* */
301 /* External : */
302 /* d_out - conversion of akku */
303 /* */
304 /* Globals : dm - I/O-buffer */
305 /* */
306 /* Author : M.Rauch */
307 /* Date : 1990-09-30 */
308 /* */
309 /****************************************************************/
310 
311 
312 
313 #include "dot_defs.hpp"
314 #include <stdlib.h>
315 
316 namespace cxsc {
317 
318 /* ---------------------------------------------------------------- */
319 /* ---------------------------------------------------------------- */
320 /* Stringbreich zur Aufnahme eines Akku */
321 
322 /* char dm[A_DIGITS]; */
323 #if _WIN32
324 __declspec(thread) char *dm = NULL;
325 __declspec(thread) char *dmhlp = NULL;
326 #elif __APPLE__ && !CXSC_FORCE_TLS
327 char *dm = NULL;
328 char *dmhlp = NULL;
329 #else
330 __thread char *dm = NULL;
331 __thread char *dmhlp = NULL;
332 #endif
333 
334 /* ---------------------------------------------------------------- */
335 
336 int d_init_dm(void)
337 {
338 
339  if (dm)
340  return 1;
341 
342  dmhlp = (char*) malloc (A_DIGITS);
343  dm = (char*) malloc (A_DIGITS);
344 
345  return (dm && dmhlp) ? 0 : -1;
346 }
347 
348 /* ---------------------------------------------------------------- */
349 
350 void d_outp(char *buffer, Dotprecision c,
351  int FormatFlag, int FracDigits, int rnd,
352  int *length)
353 
354 {
355  a_intg dexpo,bdp,len;
356  a_intg expo,i,digits,IntDigits,DecPlaces,vz;
357  a_intg HoldWidth = (FracDigits < 0);
358  char *s,*p;
359 
360 #if TEST
361  printf("d_outp\n");
362 #endif
363 
364  if (HoldWidth) FracDigits = -FracDigits;
365 
366 /* */
367 /* Kehre n�tigenfalls Rundungsrichtung um */
368 /* */
369 
370  if ((vz = (a_intg)c[A_SIGN]) != 0) {
371  rnd = -rnd;
372  }
373 
374  bdp = 2+A_I_DIGITS;
375  len = bdp+1;
376  if (c[A_END] > A_D_P) len += B_LENGTH * ((a_intg)c[A_END] - A_D_P);
377 
378  d_out (&dexpo, dm, &bdp, &len, c);
379  dm[len] = '0';
380 
381 /* */
382 /* floating-point reprensentation */
383 /* */
384 
385  /* erzwinge n�tigenfalls Gleitkommadarstellung */
386 
387  if (FormatFlag > 0 && FormatFlag-FracDigits <= 2) {
388  FormatFlag = FracDigits+3;
389  }
390  if (FormatFlag > 0) {
391  if (dexpo < -((FracDigits+1)/2) ||
392  (dexpo > 0 && dexpo >= FormatFlag-FracDigits-2)) {
393  FormatFlag = -1;
394  if (HoldWidth) {
395  FracDigits = (FracDigits < 6) ? 0 : FracDigits-6;
396  }
397  }
398  }
399 
400  if (FormatFlag == -1)
401  {
402  DecPlaces = FracDigits;
403  digits = (len - bdp - 1) + (dexpo + 1);
404  if (digits < DecPlaces) DecPlaces = digits-1;
405 
406  b_rnd (rnd, dm, digits+1, DecPlaces+1, &bdp, &dexpo);
407 
408  p = buffer;
409  *p++ = (vz) ? '-' : '+'; /* Vorzeichen */
410  s = &dm[bdp-dexpo];
411  *p++ = *s++; /* Digit vor Dezimalpunkt */
412  if (FracDigits) {
413  *p++ = '.'; /* Dezimalpunkt */
414  for (i=0;i<DecPlaces;i++) *p++ = *s++; /* Nachkommadigits */
415  for (;i<FracDigits;i++) *p++ = '0'; /* Nachkommadigits mit '0' */
416  }
417  *p++ = 'E'; /* Exponentzeichen 'E' */
418  *p++ = (dexpo<0) ? '-' : '+'; /* Vorzeichen Exponent */
419  expo = (dexpo<0) ? -dexpo : dexpo;
420  for (i=A_E_DIGITS-1; i >= 0; i--) { /* Exponent */
421  p[i] = expo%10 + '0';
422  expo /= 10;
423  }
424  *length = 3+FracDigits+2+A_E_DIGITS;
425  }
426 
427 /* */
428 /* fixed-point reprensentation */
429 /* */
430 
431  else
432  {
433  DecPlaces = (FracDigits < (len-bdp-1)) ? FracDigits : (len-bdp-1);
434  if (dexpo >= 0) {
435  IntDigits = dexpo+1;
436  }
437  else {
438  IntDigits = 1;
439  for (i=0; i < -dexpo; i++) dm[bdp+i] = '0';
440  dexpo = 0;
441  }
442  digits = (len - bdp - 1) + (dexpo + 1);
443 
444  b_rnd (rnd, dm, digits+1, IntDigits+DecPlaces, &bdp, &dexpo);
445 
446  p = buffer;
447  *p++ = (vz) ? '-' : '+'; /* Vorzeichen */
448  s = &dm[bdp-IntDigits+1];
449  for(i=0;i<IntDigits;i++) *p++ = *s++; /* Digits vor Dezimalpunkt */
450  if (FracDigits) {
451  *p++ = '.'; /* Dezimalpunkt */
452  for (i=0;i<DecPlaces;i++) *p++ = *s++; /* Nachkommadigits */
453  for (;i<FracDigits;i++) *p++ = '0'; /* Nachkommadigits mit 0 */
454  }
455  *length = IntDigits+FracDigits+2;
456  }
457  if (FracDigits == 0) (*length)--;
458  buffer[*length] = '\0';
459 }
460 
461 /****************************************************************/
462 /* */
463 /* Filename : d_out.c */
464 /* */
465 /* Entries : void d_out */
466 /* (dexpo,buffer,bdp,len,c) 4 */
467 /* a_intg *dexpo,*bdp,*len; */
468 /* char *buffer; */
469 /* dotprecision c; */
470 /* */
471 /* Arguments : */
472 /* dexpo - decimal exponent of first */
473 /* digit */
474 /* buffer - output string */
475 /* bdp - position of decimal point */
476 /* len - input: usable size of buffer */
477 /* output: totaly produced digits */
478 /* c - accu for output */
479 /* */
480 /* */
481 /* Description : Decimal representation determined from*/
482 /* dotprecision akku */
483 /* */
484 /* External : */
485 /* b_outf - conversion of fractional part*/
486 /* b_outi - conversion of integer part */
487 /* */
488 /* Globals : b_cm__ - I/O-buffer */
489 /* */
490 /* Author : M.Rauch */
491 /* Date : 1990-09-30 */
492 /****************************************************************/
493 
494 }
495 // #include "o_defs.h"
496 #if WINDOWS_X86_32
497 #include "dot.hpp"
498 Dotprecision b_cm__;
499 #else
500 extern Dotprecision b_cm__;
501 #endif
502 
503 namespace cxsc {
504 void d_out(a_intg *dexpo, char *buffer, a_intg *bdp, a_intg *len,
505  Dotprecision c)
506 
507 {
508  a_intg i,digits,cont;
509 
510 #if TEST
511  printf("d_out\n");
512 #endif
513 
514 /* copy akku c to temporary akku b_cm__ */
515 
516  b_cm__[A_BEGIN] = c[A_BEGIN];
517  b_cm__[A_END] = c[A_END];
518  for (i=(a_intg)c[A_BEGIN]; i <= (a_intg)c[A_END]; i++)
519  b_cm__[i] = c[i];
520 
521 /* test if akku is zero */
522 
523  if (b_cm__[A_BEGIN]==ZERO || b_cm__[A_END]==ZERO || b_cm__[A_BEGIN]>b_cm__[A_END]) {
524  buffer[*bdp] = '0';
525  for (i=*bdp+1; i < *len; i++) buffer[i] = '0';
526  *dexpo = 0;
527  return;
528  }
529 
530  /* clear accu contents between number and decimal point */
531  for (i=(a_intg)b_cm__[A_END]+1; i <= A_D_P; i++)
532  b_cm__[i] = ZERO;
533  for (i=A_D_P+1; i < (a_intg)b_cm__[A_BEGIN]; i++)
534  b_cm__[i] = ZERO;
535 
536 /* */
537 /* conversion of integer part */
538 /* */
539 
540  *dexpo = -1;
541  if (b_cm__[A_BEGIN] <= A_D_P) {
542  digits = *len;
543  b_outi(&digits,buffer,bdp,dexpo,b_cm__);
544  }
545 
546 /* */
547 /* conversion of fraction part */
548 /* */
549 
550  digits = (*len < *bdp+1) ? 0 : *len - *bdp - 1;
551  if (digits>0) {
552  cont = 0;
553  b_outf(&digits,buffer,bdp,&cont,b_cm__);
554  if (*dexpo < 0) {
555  for (cont=*bdp+1; cont < *len-1; cont++) {
556  if (buffer[cont] != '0') break;
557  (*dexpo)--;
558  }
559  }
560  }
561 
562  return;
563 }
564 
565 /****************************************************************/
566 /* */
567 /* Filename : d_scanp.c */
568 /* */
569 /* Entries : char* d_scanp (c,inpbuf,rnd,rndfl) */
570 /* dotprecision c; */
571 /* char *inpbuf; */
572 /* a_intg rnd,*rndfl; */
573 /* */
574 /* Arguments : */
575 /* c - accu holding IEEE value */
576 /* inpbuf - buffer with input digits */
577 /* rnd - direction of rounding */
578 /* rndfl - flag 'rounding occurred' */
579 /* */
580 /* Description : Convert a character string */
581 /* to the corresponding IEEE value */
582 /* */
583 /* Author : M.Rauch, University of Karlsruhe */
584 /* Date : 1990-10-20 */
585 /****************************************************************/
586 
587 
588 char* d_scanp(Dotprecision c, char *inpbuf, a_intg rnd, a_intg *rndfl)
589 {
590  char *s;
591  a_intg sign, dexpo, bdp, len;
592  a_btyp *p,*pe;
593 /* */
594 /* convert input string into a convertible form */
595 /* */
596 
597  s = d_scan (inpbuf, &sign, &dexpo, dm, &bdp, &len);
598 
599 /* */
600 /* change rnd-direction if input string is negativ */
601 /* */
602 
603  c[A_SIGN] = sign;
604  if (sign && rnd)
605  rnd = -rnd;
606 
607 /* */
608 /* convert integer and fractional parts */
609 /* */
610 
611  d_scani (c, dm, &dexpo, &bdp, &len);
612  *rndfl = d_scanf (c, dm, &dexpo, &bdp, &len, rnd);
613 
614 /* */
615 /* adjust akku and test if akku is ZERO */
616 /* */
617 
618  for (p=&c[(a_intg)c[A_BEGIN]],pe=&c[(a_intg)c[A_END]]; p <= pe; p++)
619  {
620  if (*p != ZERO)
621  break;
622  c[A_BEGIN]++;
623  }
624  for (; pe >= p; pe--)
625  {
626  if (*pe != ZERO)
627  break;
628  c[A_END]--;
629  }
630  if (p > pe)
631  {
632  c[A_BEGIN] = c[A_END] = 0;
633  }
634 
635  c[A_STATUS] |= A_PZERO+A_MZERO;
636  return s;
637 }
638 
639 /****************************************************************/
640 /* */
641 /* Filename : d_scani.c */
642 /* */
643 /* Entries : d_scani (c, buffer, dexpo, bdp, len) */
644 /* Dotprecision c; */
645 /* char *buffer; */
646 /* int *dexpo,*bdp,*len; */
647 /* */
648 /* Arguments : */
649 /* c - accu holding IEEE value */
650 /* buffer - buffer with input digits */
651 /* bdp - position of decimal point */
652 /* dexpo - exponent of first non-zero */
653 /* digit */
654 /* len - position behind last input digit*/
655 /* */
656 /* Description : Convert a character string */
657 /* to the integer part of IEEE value */
658 /* */
659 /* Author : M.Rauch, University of Karlsruhe */
660 /* Date : 1990-10-19 */
661 /****************************************************************/
662 
663 
664 void d_scani(Dotprecision c, char *buffer, a_intg *dexpo,
665  a_intg *bdp, a_intg *len)
666 
667 {
668  a_intg i,j;
669  a_btyp carry;
670  a_btyp *s,*p,h,hh;
671  char *q,*qe;
672 
673 /* */
674 /* initialize */
675 /* */
676  c[A_BEGIN] = c[A_END] = A_D_P,
677  c[A_D_P] = ZERO;
678  if (*dexpo < 0)
679  return;
680 
681  i = (*dexpo+1) % B2D_LOG10;
682  if (i)
683  {
684  q = buffer + *bdp - *dexpo - 1;
685  for (; i < B2D_LOG10; i++,(*dexpo)++,q--)
686  *q = '0';
687  }
688  for (i=*len; i <= *bdp; i++)
689  buffer[i] = '0';
690 
691  q = buffer + *bdp - *dexpo;
692  qe = buffer + *bdp;
693  s = &c[(a_intg)c[A_BEGIN]];
694 
695 /* */
696 /* convert by repeated multiplication */
697 /* */
698 
699  while (q < qe)
700  {
701  /* get decimal digits */
702  for (j=0,i=B2D_LOG10;i>0;i--,q++)
703  {
704  /* carry = 10*carry + *q - '0'; */
705  j = j*10 + *q - '0';
706  }
707  carry = j;
708 
709  for (p=&c[A_D_P]; p >= s; p--)
710  {
711  hh = GETLOW(*p)*B2D_POWER+carry,
712  h = GETHIGH(*p)*B2D_POWER+GETHIGH(hh),
713  carry = GETHIGH(h),
714  *p = MOVEHIGH(h) | GETLOW(hh);
715  }
716 
717  /* adjust digits */
718  if (carry)
719  {
720  c[A_BEGIN]--, s--;
721  *s = carry;
722  }
723 
724  }
725  return;
726 }
727 
728 /****************************************************************/
729 /* */
730 /* Filename : d_scanf.c */
731 /* */
732 /* Entries : a_intg d_scanf (c,buffer,dexpo,bdp,len,rnd) */
733 /* Dotprecision c; */
734 /* char *buffer; */
735 /* a_intg *dexpo,*bdp,*len,rnd; */
736 /* */
737 /* Arguments : */
738 /* c - accu holding IEEE value */
739 /* buffer - buffer with input digits */
740 /* bdp - position of decimal point */
741 /* dexpo - exponent of first non-zero */
742 /* digit */
743 /* len - position behind last input digit*/
744 /* rnd - direction of rounding */
745 /* */
746 /* Description : Convert a character string */
747 /* to the fractional part of IEEE value */
748 /* */
749 /* Author : M.Rauch, University of Karlsruhe */
750 /* Date : 1990-10-19 */
751 /****************************************************************/
752 
753 
754 a_intg d_scanf(Dotprecision c, char *buffer, a_intg *dexpo,
755  a_intg *bdp, a_intg *len, a_intg rnd)
756 
757 {
758  a_intg i,j,rndflag = 0;
759  a_btyp mod, carry;
760  a_btyp *s,*p,*pe,h,hh;
761  char *q,*qe;
762 
763 
764 /* */
765 /* initialize */
766 /* */
767 
768  if (*len+1 <= *bdp)
769  return rndflag;
770 
771  for (i=*bdp-*dexpo; *dexpo < 0; (*dexpo)++,i--)
772  buffer[i] = '0';
773 
774  i = (*len - *bdp - 1) % B2D_LOG10;
775  if (i)
776  {
777  q = buffer + *len;
778  for (; i < B2D_LOG10; i++,(*len)++,q++)
779  *q = '0';
780  }
781 
782  qe = buffer + *bdp + 1;
783  q = buffer + *len;
784  s = &c[(a_intg)c[A_END]];
785 
786 /* */
787 /* convert by repeated division */
788 /* */
789 
790  carry = 0;
791  while (q > qe)
792  {
793  /* get decimal digits */
794  for (q-=B2D_LOG10,j=i=0;i<B2D_LOG10;i++)
795  {
796  /* mod = 10*mod + q[i] - '0'; */
797  j = j*10 + q[i] - '0';
798  }
799  mod = j + carry;
800  if (mod == B2D_POWER)
801  {
802  carry = 1, mod = 0;
803  } else
804  carry = 0;
805 
806  p=&c[A_D_P+1];
807 
808  do {
809  for (;p<=s;p++)
810  {
811  h = GETHIGH(*p) | MOVEHIGH(mod),
812  hh = GETLOW(*p) | MOVEHIGH(h%B2D_POWER),
813  mod = hh%B2D_POWER,
814  *p = MOVEHIGH(h/B2D_POWER) | (hh/B2D_POWER);
815  }
816  if (mod && c[A_END] < A_LENGTH-1)
817  {
818  c[A_END]++, s++;
819  *s = ZERO;
820  }
821  } while (p <= s);
822 
823  if (mod)
824  rndflag = 1;
825 
826  if (rnd < 0)
827  mod = 0;
828  else if (rnd == 0 && mod < B2D_POWER/2)
829  mod = 0;
830 
831  if (mod)
832  {
833  /* Runden nach oben : c um 1 Inkermentieren */
834 
835  p = &c[A_LENGTH-1], /* == s */
836  pe = &c[A_D_P+1];
837  for(; p >= pe; p--)
838  {
839  (*p)++;
840  if (*p)
841  break;
842  }
843  if (p < pe)
844  carry = 1;
845 
846  }
847  }
848 
849  if (carry)
850  {
851  p = &c[A_D_P];
852  pe = &c[(a_intg)c[A_BEGIN]];
853  for(; p >= pe; p--)
854  {
855  (*p)++;
856  if (*p)
857  break;
858  }
859  if (p < pe)
860  {
861  --c[A_BEGIN];
862  *p = 1;
863  }
864  }
865 
866  return rndflag;
867 }
868 
869 /****************************************************************/
870 /* */
871 /* Filename : d_scan.c */
872 /* */
873 /* Entries : char* d_scan.c */
874 /* (inpbuf, sign,dexpo,outbuf,bdp,len) */
875 /* a_intg *sign,*dexpo,*bdp,*len; */
876 /* char *inpbuf, *outbuf; */
877 /* */
878 /* Arguments : */
879 /* inpbuf - string to scan */
880 /* Returnvalues : */
881 /* sign - sign flag */
882 /* dexpo - decimal exponent of first */
883 /* digit */
884 /* outbuf - output string */
885 /* min.length: A_DIGITS */
886 /* bdp - position of decimal point */
887 /* len - totaly produced digits */
888 /* output: totaly produced digits */
889 /* c - accu for output */
890 /* */
891 /* */
892 /* Description : the input string is scanned and */
893 /* transferred into an ordered form */
894 /* */
895 /* Author : M.Rauch */
896 /* Date : 1990-10-14 */
897 /****************************************************************/
898 
899 
900 char* d_scan (char *inpbuf, a_intg *sign, a_intg *dexpo,
901  char *outbuf, a_intg *bdp, a_intg *len)
902 
903 {
904  a_intg start, point, mantend, expo, end;
905  a_intg digits,fl,i,j;
906  char c;
907 
908  /* intialiaze parameters */
909 
910  *bdp = 1 + A_I_DIGITS;
911  *len = (*bdp)+1;
912  *dexpo = 0;
913 
914  /* */
915  /* determine structure of input string */
916  /* */
917 
918  fl = 0;
919  for (start=0; (c = inpbuf[start]) != 0; start++)
920  { /* skip white spaces */
921  if (c > ' ')
922  break;
923  }
924 
925  if (c == '-' || c == '+') /* determine sign */
926  *sign = ((c == '-') ? 1 : 0),
927  start++;
928  else
929  *sign = 0;
930 
931  for (; (c = inpbuf[start]) != 0; start++)
932  { /* skip white spaces */
933  if (c > ' ')
934  break;
935  }
936  for (; (c = inpbuf[start]) != 0; start++)
937  { /* skip leading zero */
938  if (c != '0')
939  break;
940  }
941 
942  for (end=start; (c = inpbuf[end]) != 0; end++)
943  { /* skip intdigits */
944  if (c < '0' || c > '9')
945  break;
946  }
947  if (c == '.') /* pos. of decimalpoint */
948  point = end,
949  end++,
950  fl++;
951  else
952  point = -1;
953 
954  for (; (c = inpbuf[end]) != 0; end++)
955  { /* skip fracdigits */
956  if (c < '0' || c > '9')
957  break;
958  }
959  mantend = end; /* end of mantissa */
960 
961  if (c == 'E' || c == 'e') /* determine exponent */
962  {
963  c = inpbuf[++end];
964  if (c == '+' || c == '-') /* sign of exponent */
965  expo = ((c == '-') ? 1 : 0),
966  end++;
967  else
968  expo = 0;
969  for (i=0; (c = inpbuf[end]) != 0; end++)
970  { /* value of exponent */
971  if (c < '0' || c > '9')
972  break;
973  if (i >= (A_E_MAX/10))
974  {
975  break; /* Error Exponent To big ---- mr???? */
976  }
977  i = 10*i + c - '0';
978  }
979  expo = expo ? -i : i;
980  } else
981  expo = 0;
982 
983  if (c)
984  end++; /* skip at least one delimeter char */
985 
986  /* */
987  /* check if there are some digits in the mantissa */
988  /* */
989 
990  if (start+fl == mantend)
991  {
992  outbuf[*bdp] = '0';
993  return &inpbuf[end];
994  }
995 
996  if (point != -1)
997  {
998  digits = mantend - start - 1;
999  *dexpo = (point - start - 1) + expo;
1000  if (start == point) digits++,
1001  (*dexpo)++;
1002  } else
1003  {
1004  digits = mantend - start;
1005  *dexpo = (mantend - start - 1) + expo;
1006  }
1007 
1008  if (*dexpo >= (A_I_DIGITS-10))
1009  {
1010  /* Error Input Value Too big ---- mr ???? */
1011  }
1012  if (*dexpo <= - (A_F_DIGITS-10))
1013  {
1014  /* Error Input Value Too small ---- mr ???? */
1015  }
1016 
1017  /* */
1018  /* take known digits into output string */
1019  /* */
1020 
1021  *len = *bdp - *dexpo + digits;
1022  if (*len >= A_DIGITS)
1023  {
1024  /* Error Input String Too long ---- mr ???? */
1025  }
1026  for (j=*len-1,i=mantend-1; i >= start; i--)
1027  {
1028  if ((c = inpbuf[i]) != '.')
1029  outbuf[j--] = c;
1030  }
1031  if (start == point)
1032  outbuf[j] = '0';
1033 
1034  /* */
1035  /* be shure that the decimal point is in the output string */
1036  /* */
1037 
1038  if (*dexpo < 0)
1039  {
1040  for (j=-*dexpo,i=*bdp-*dexpo-1; j > 0; j--,i--)
1041  outbuf[i] = '0';
1042  *dexpo = 0;
1043  }
1044 
1045  if (*len <= *bdp)
1046  {
1047  for (j=(*bdp)-(*len)+1,i=*len; j > 0; j--,i++)
1048  outbuf[i] = '0';
1049  *len = (*bdp)+1;
1050  }
1051 
1052  return &inpbuf[end];
1053 }
1054 
1055 } // namespace cxsc
1056 
The Data Type dotprecision.
Definition: dot.hpp:111
The namespace cxsc, providing all functionality of the class library C-XSC.
Definition: cdot.cpp:29
The Scalar Type real.
Definition: real.hpp:113