]> www.ginac.de Git - cln.git/blob - src/integer/conv/cl_I_from_digits.cc
5fc3426d56f8dacc74781b4e80fdb7198a59762b
[cln.git] / src / integer / conv / cl_I_from_digits.cc
1 // digits_to_I().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_I.h"
8
9
10 // Implementation.
11
12 #include "cl_DS.h"
13
14 namespace cln {
15
16 const cl_I digits_to_I (const char * MSBptr, uintL len, uintD base)
17 {
18       CL_ALLOCA_STACK;
19       var uintD* erg_MSDptr;
20       var uintC erg_len;
21       var uintD* erg_LSDptr;
22       // Platz fürs Ergebnis:
23       // 1+ceiling(len*log(base)/(intDsize*log(2))) oder etwas mehr Digits
24       var uintL need = 1+floor(len,intDsize*256); // > len/(intDsize*256) >=0
25       switch (base) // need mit ceiling(256*log(base)/log(2)) multiplizieren:
26         { case 2: need = 256*need; break;
27           case 3: need = 406*need; break;
28           case 4: need = 512*need; break;
29           case 5: need = 595*need; break;
30           case 6: need = 662*need; break;
31           case 7: need = 719*need; break;
32           case 8: need = 768*need; break;
33           case 9: need = 812*need; break;
34           case 10: need = 851*need; break;
35           case 11: need = 886*need; break;
36           case 12: need = 918*need; break;
37           case 13: need = 948*need; break;
38           case 14: need = 975*need; break;
39           case 15: need = 1001*need; break;
40           case 16: need = 1024*need; break;
41           case 17: need = 1047*need; break;
42           case 18: need = 1068*need; break;
43           case 19: need = 1088*need; break;
44           case 20: need = 1107*need; break;
45           case 21: need = 1125*need; break;
46           case 22: need = 1142*need; break;
47           case 23: need = 1159*need; break;
48           case 24: need = 1174*need; break;
49           case 25: need = 1189*need; break;
50           case 26: need = 1204*need; break;
51           case 27: need = 1218*need; break;
52           case 28: need = 1231*need; break;
53           case 29: need = 1244*need; break;
54           case 30: need = 1257*need; break;
55           case 31: need = 1269*need; break;
56           case 32: need = 1280*need; break;
57           case 33: need = 1292*need; break;
58           case 34: need = 1303*need; break;
59           case 35: need = 1314*need; break;
60           case 36: need = 1324*need; break;
61           default: NOTREACHED
62         }
63       // Nun gilt need >= len*log(base)/(intDsize*log(2)).
64       need += 1;
65       num_stack_alloc(need,,erg_LSDptr=);
66       erg_MSDptr = erg_LSDptr; erg_len = 0;
67       // Ziffern einzeln draufaddieren:
68       while (len > 0)
69         { // erg_MSDptr/erg_len/erg_LSDptr ist eine NUDS, erg_len < need.
70           var uintB ch = *(const uintB *)MSBptr; MSBptr++; // nächstes Character
71           if (!(ch=='.')) // Punkt überlesen
72             { // Wert von ch ('0'-'9','A'-'Z','a'-'z') bilden:
73               ch = ch - '0';
74               if (ch > '9'-'0') // keine Ziffer?
75                 { ch = ch+'0'-'A'+10;
76                   if (ch > 'Z'-'A'+10) // kein Großbuchstabe?
77                     { ch = ch+'A'-'a'; } // dann ein Kleinbuchstabe
78                 }
79               // multipliziere erg mit base und addiere ch:
80              {var uintD carry = mulusmall_loop_lsp(base,erg_LSDptr,erg_len,ch);
81               if (!(carry==0))
82                 // muß NUDS vergrößern:
83                 { lsprefnext(erg_MSDptr) = carry; erg_len++; }
84             }}
85           len--;
86         }
87       return NUDS_to_I(erg_MSDptr,erg_len);
88 }
89
90 }  // namespace cln