00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
00060 string sh;
00061 real rl,ru;
00062 rnd (a, rl, ru);
00063
00064 sh="dot("; sh << SaveOpt << RndDown;
00065 sh+=", "; sh << RndUp;
00066 sh+=")"; sh << RestoreOpt;
00067 s+=sh;
00068
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
00078 return s;
00079
00080
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
00135
00136
00137 }
00138
00139 a= 0.0;
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
00168 c = skipwhitespaces (s);
00169
00170
00171 if (c == '+' || c == '-')
00172 {
00173 d+=c;
00174 c = skipwhitespaces (s);
00175 }
00176
00177 if (c == '0')
00178 c = skipleadingchars (s, '0', '0');
00179
00180
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
00196 if (c == '.')
00197 {
00198 d+= '.';
00199 if (s.good())
00200 s.get(c);
00201 else
00202 inpdotflag = false,
00203 c = '\0';
00204 }
00205
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
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
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
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
00257
00258
00259
00260
00261 waseolnflag = (c == '\n');
00262
00263
00264
00265
00266 d>>a;
00267
00268 return s;
00269 }
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 #include "dot_defs.hpp"
00314 #include <stdlib.h>
00315
00316 namespace cxsc {
00317
00318
00319
00320
00321
00322
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
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
00383
00384
00385
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) ? '-' : '+';
00410 s = &dm[bdp-dexpo];
00411 *p++ = *s++;
00412 if (FracDigits) {
00413 *p++ = '.';
00414 for (i=0;i<DecPlaces;i++) *p++ = *s++;
00415 for (;i<FracDigits;i++) *p++ = '0';
00416 }
00417 *p++ = 'E';
00418 *p++ = (dexpo<0) ? '-' : '+';
00419 expo = (dexpo<0) ? -dexpo : dexpo;
00420 for (i=A_E_DIGITS-1; i >= 0; i--) {
00421 p[i] = expo%10 + '0';
00422 expo /= 10;
00423 }
00424 *length = 3+FracDigits+2+A_E_DIGITS;
00425 }
00426
00427
00428
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) ? '-' : '+';
00448 s = &dm[bdp-IntDigits+1];
00449 for(i=0;i<IntDigits;i++) *p++ = *s++;
00450 if (FracDigits) {
00451 *p++ = '.';
00452 for (i=0;i<DecPlaces;i++) *p++ = *s++;
00453 for (;i<FracDigits;i++) *p++ = '0';
00454 }
00455 *length = IntDigits+FracDigits+2;
00456 }
00457 if (FracDigits == 0) (*length)--;
00458 buffer[*length] = '\0';
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494 }
00495
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
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
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
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
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
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
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
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
00595
00596
00597 s = d_scan (inpbuf, &sign, &dexpo, dm, &bdp, &len);
00598
00599
00600
00601
00602
00603 c[A_SIGN] = sign;
00604 if (sign && rnd)
00605 rnd = -rnd;
00606
00607
00608
00609
00610
00611 d_scani (c, dm, &dexpo, &bdp, &len);
00612 *rndfl = d_scanf (c, dm, &dexpo, &bdp, &len, rnd);
00613
00614
00615
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
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
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
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
00697
00698
00699 while (q < qe)
00700 {
00701
00702 for (j=0,i=B2D_LOG10;i>0;i--,q++)
00703 {
00704
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
00718 if (carry)
00719 {
00720 c[A_BEGIN]--, s--;
00721 *s = carry;
00722 }
00723
00724 }
00725 return;
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
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
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
00788
00789
00790 carry = 0;
00791 while (q > qe)
00792 {
00793
00794 for (q-=B2D_LOG10,j=i=0;i<B2D_LOG10;i++)
00795 {
00796
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
00834
00835 p = &c[A_LENGTH-1],
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
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
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
00909
00910 *bdp = 1 + A_I_DIGITS;
00911 *len = (*bdp)+1;
00912 *dexpo = 0;
00913
00914
00915
00916
00917
00918 fl = 0;
00919 for (start=0; (c = inpbuf[start]) != 0; start++)
00920 {
00921 if (c > ' ')
00922 break;
00923 }
00924
00925 if (c == '-' || c == '+')
00926 *sign = ((c == '-') ? 1 : 0),
00927 start++;
00928 else
00929 *sign = 0;
00930
00931 for (; (c = inpbuf[start]) != 0; start++)
00932 {
00933 if (c > ' ')
00934 break;
00935 }
00936 for (; (c = inpbuf[start]) != 0; start++)
00937 {
00938 if (c != '0')
00939 break;
00940 }
00941
00942 for (end=start; (c = inpbuf[end]) != 0; end++)
00943 {
00944 if (c < '0' || c > '9')
00945 break;
00946 }
00947 if (c == '.')
00948 point = end,
00949 end++,
00950 fl++;
00951 else
00952 point = -1;
00953
00954 for (; (c = inpbuf[end]) != 0; end++)
00955 {
00956 if (c < '0' || c > '9')
00957 break;
00958 }
00959 mantend = end;
00960
00961 if (c == 'E' || c == 'e')
00962 {
00963 c = inpbuf[++end];
00964 if (c == '+' || c == '-')
00965 expo = ((c == '-') ? 1 : 0),
00966 end++;
00967 else
00968 expo = 0;
00969 for (i=0; (c = inpbuf[end]) != 0; end++)
00970 {
00971 if (c < '0' || c > '9')
00972 break;
00973 if (i >= (A_E_MAX/10))
00974 {
00975 break;
00976 }
00977 i = 10*i + c - '0';
00978 }
00979 expo = expo ? -i : i;
00980 } else
00981 expo = 0;
00982
00983 if (c)
00984 end++;
00985
00986
00987
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
01011 }
01012 if (*dexpo <= - (A_F_DIGITS-10))
01013 {
01014
01015 }
01016
01017
01018
01019
01020
01021 *len = *bdp - *dexpo + digits;
01022 if (*len >= A_DIGITS)
01023 {
01024
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
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 }
01056