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