14 // Tabelle: enthält zu jeder Basis b (2 <= b <= 36)
15 // - eine Kettenbruchapproximation num/den von intDsize*log(2)/log(b)
16 // (num/den >= intDsize*log(2)/log(b), mit num <= 2^10)
17 // - k-1 und b^k mit b^k < 2^intDsize, k maximal.
18 typedef struct { /* uintW num,den; */ uintC k_1; uintD b_hoch_k; } power_table_entry;
19 static power_table_entry table [36-2+1] = {
21 { /* 8, 1, */ 7-1, 2*2*2*2*2*2*2},
22 { /* 106, 21, */ 5-1, 3*3*3*3*3},
23 { /* 4, 1, */ 3-1, 4*4*4},
24 { /* 789,229, */ 3-1, 5*5*5},
25 { /* 359,116, */ 3-1, 6*6*6},
26 { /* 436,153, */ 2-1, 7*7},
27 { /* 8, 3, */ 2-1, 8*8},
28 { /* 53, 21, */ 2-1, 9*9},
29 { /* 525,218, */ 2-1, 10*10},
30 { /* 1006,435, */ 2-1, 11*11},
31 { /* 665,298, */ 2-1, 12*12},
32 { /* 988,457, */ 2-1, 13*13},
33 { /* 872,415, */ 2-1, 14*14},
34 { /* 987,482, */ 2-1, 15*15},
35 { /* 2, 1, */ 1-1, 16},
36 { /* 869,444, */ 1-1, 17},
37 { /* 871,454, */ 1-1, 18},
38 { /* 597,317, */ 1-1, 19},
39 { /* 87, 47, */ 1-1, 20},
40 { /* 989,543, */ 1-1, 21},
41 { /* 949,529, */ 1-1, 22},
42 { /* 191,108, */ 1-1, 23},
43 { /* 930,533, */ 1-1, 24},
44 { /* 789,458, */ 1-1, 25},
45 { /* 691,406, */ 1-1, 26},
46 { /* 461,274, */ 1-1, 27},
47 { /* 218,131, */ 1-1, 28},
48 { /* 690,419, */ 1-1, 29},
49 { /* 494,303, */ 1-1, 30},
50 { /* 633,392, */ 1-1, 31},
51 { /* 8, 5, */ 1-1, 32},
52 { /* 766,483, */ 1-1, 33},
53 { /* 629,400, */ 1-1, 34},
54 { /* 967,620, */ 1-1, 35},
55 { /* 359,232, */ 1-1, 36},
58 { /* 16, 1, */ 15-1, 2*2*2*2*2*2*2*2*2*2*2*2*2*2*2},
59 { /* 212, 21, */ 10-1, 3*3*3*3*3*3*3*3*3*3},
60 { /* 8, 1, */ 7-1, 4*4*4*4*4*4*4},
61 { /* 379, 55, */ 6-1, 5*5*5*5*5*5},
62 { /* 359, 58, */ 6-1, 6*6*6*6*6*6},
63 { /* 872,153, */ 5-1, 7*7*7*7*7},
64 { /* 16, 3, */ 5-1, 8*8*8*8*8},
65 { /* 106, 21, */ 5-1, 9*9*9*9*9},
66 { /* 525,109, */ 4-1, 10*10*10*10},
67 { /* 1013,219, */ 4-1, 11*11*11*11},
68 { /* 665,149, */ 4-1, 12*12*12*12},
69 { /* 761,176, */ 4-1, 13*13*13*13},
70 { /* 685,163, */ 4-1, 14*14*14*14},
71 { /* 987,241, */ 4-1, 15*15*15*15},
72 { /* 4, 1, */ 3-1, 16*16*16},
73 { /* 869,222, */ 3-1, 17*17*17},
74 { /* 871,227, */ 3-1, 18*18*18},
75 { /* 113, 30, */ 3-1, 19*19*19},
76 { /* 174, 47, */ 3-1, 20*20*20},
77 { /* 51, 14, */ 3-1, 21*21*21},
78 { /* 653,182, */ 3-1, 22*22*22},
79 { /* 191, 54, */ 3-1, 23*23*23},
80 { /* 677,194, */ 3-1, 24*24*24},
81 { /* 789,229, */ 3-1, 25*25*25},
82 { /* 691,203, */ 3-1, 26*26*26},
83 { /* 461,137, */ 3-1, 27*27*27},
84 { /* 436,131, */ 3-1, 28*28*28},
85 { /* 359,109, */ 3-1, 29*29*29},
86 { /* 988,303, */ 3-1, 30*30*30},
87 { /* 633,196, */ 3-1, 31*31*31},
88 { /* 16, 5, */ 3-1, 32*32*32},
89 { /* 203, 64, */ 3-1, 33*33*33},
90 { /* 629,200, */ 3-1, 34*34*34},
91 { /* 967,310, */ 3-1, 35*35*35},
92 { /* 359,116, */ 3-1, 36*36*36},
95 { /* 32, 1, */ 31-1, 2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL},
96 { /* 424, 21, */ 20-1, 3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL},
97 { /* 16, 1, */ 15-1, 4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL},
98 { /* 758, 55, */ 13-1, 5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL},
99 { /* 359, 29, */ 12-1, 6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL},
100 { /* 57, 5, */ 11-1, 7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL},
101 { /* 32, 3, */ 10-1, 8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL},
102 { /* 212, 21, */ 10-1, 9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL},
103 { /* 289, 30, */ 9-1, 10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL},
104 { /* 990,107, */ 9-1, 11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL},
105 { /* 848, 95, */ 8-1, 12UL*12UL*12UL*12UL*12UL*12UL*12UL*12UL},
106 { /* 761, 88, */ 8-1, 13UL*13UL*13UL*13UL*13UL*13UL*13UL*13UL},
107 { /* 1017,121, */ 8-1, 14UL*14UL*14UL*14UL*14UL*14UL*14UL*14UL},
108 { /* 901,110, */ 8-1, 15UL*15UL*15UL*15UL*15UL*15UL*15UL*15UL},
109 { /* 8, 1, */ 7-1, 16UL*16UL*16UL*16UL*16UL*16UL*16UL},
110 { /* 869,111, */ 7-1, 17UL*17UL*17UL*17UL*17UL*17UL*17UL},
111 { /* 683, 89, */ 7-1, 18UL*18UL*18UL*18UL*18UL*18UL*18UL},
112 { /* 113, 15, */ 7-1, 19UL*19UL*19UL*19UL*19UL*19UL*19UL},
113 { /* 348, 47, */ 7-1, 20UL*20UL*20UL*20UL*20UL*20UL*20UL},
114 { /* 51, 7, */ 7-1, 21UL*21UL*21UL*21UL*21UL*21UL*21UL},
115 { /* 653, 91, */ 7-1, 22UL*22UL*22UL*22UL*22UL*22UL*22UL},
116 { /* 191, 27, */ 7-1, 23UL*23UL*23UL*23UL*23UL*23UL*23UL},
117 { /* 677, 97, */ 6-1, 24UL*24UL*24UL*24UL*24UL*24UL},
118 { /* 379, 55, */ 6-1, 25UL*25UL*25UL*25UL*25UL*25UL},
119 { /* 851,125, */ 6-1, 26UL*26UL*26UL*26UL*26UL*26UL},
120 { /* 922,137, */ 6-1, 27UL*27UL*27UL*27UL*27UL*27UL},
121 { /* 872,131, */ 6-1, 28UL*28UL*28UL*28UL*28UL*28UL},
122 { /* 718,109, */ 6-1, 29UL*29UL*29UL*29UL*29UL*29UL},
123 { /* 150, 23, */ 6-1, 30UL*30UL*30UL*30UL*30UL*30UL},
124 { /* 633, 98, */ 6-1, 31UL*31UL*31UL*31UL*31UL*31UL},
125 { /* 32, 5, */ 6-1, 32UL*32UL*32UL*32UL*32UL*32UL},
126 { /* 203, 32, */ 6-1, 33UL*33UL*33UL*33UL*33UL*33UL},
127 { /* 629,100, */ 6-1, 34UL*34UL*34UL*34UL*34UL*34UL},
128 { /* 967,155, */ 6-1, 35UL*35UL*35UL*35UL*35UL*35UL},
129 { /* 359, 58, */ 6-1, 36UL*36UL*36UL*36UL*36UL*36UL},
132 { /* 64, 1, */ 63-1, 2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL*2UL},
133 { /* 848, 21, */ 40-1, 3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL*3UL},
134 { /* 32, 1, */ 31-1, 4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL*4UL},
135 { /* 634, 23, */ 27-1, 5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL*5UL},
136 { /* 718, 29, */ 24-1, 6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL*6UL},
137 { /* 114, 5, */ 22-1, 7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL*7UL},
138 { /* 64, 3, */ 21-1, 8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL*8UL},
139 { /* 424, 21, */ 20-1, 9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL*9UL},
140 { /* 289, 15, */ 19-1, 10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL*10UL},
141 { /* 1018, 55, */ 18-1, 11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL*11UL},
142 { /* 607, 34, */ 17-1, 12UL*12UL*12UL*12UL*12UL*12UL*12UL*12UL*12UL*12UL*12UL*12UL*12UL*12UL*12UL*12UL*12UL},
143 { /* 761, 44, */ 17-1, 13UL*13UL*13UL*13UL*13UL*13UL*13UL*13UL*13UL*13UL*13UL*13UL*13UL*13UL*13UL*13UL*13UL},
144 { /* 975, 58, */ 16-1, 14UL*14UL*14UL*14UL*14UL*14UL*14UL*14UL*14UL*14UL*14UL*14UL*14UL*14UL*14UL*14UL},
145 { /* 901, 55, */ 16-1, 15UL*15UL*15UL*15UL*15UL*15UL*15UL*15UL*15UL*15UL*15UL*15UL*15UL*15UL*15UL*15UL},
146 { /* 16, 1, */ 15-1, 16UL*16UL*16UL*16UL*16UL*16UL*16UL*16UL*16UL*16UL*16UL*16UL*16UL*16UL*16UL},
147 { /* 595, 38, */ 15-1, 17UL*17UL*17UL*17UL*17UL*17UL*17UL*17UL*17UL*17UL*17UL*17UL*17UL*17UL*17UL},
148 { /* 1013, 66, */ 15-1, 18UL*18UL*18UL*18UL*18UL*18UL*18UL*18UL*18UL*18UL*18UL*18UL*18UL*18UL*18UL},
149 { /* 226, 15, */ 15-1, 19UL*19UL*19UL*19UL*19UL*19UL*19UL*19UL*19UL*19UL*19UL*19UL*19UL*19UL*19UL},
150 { /* 696, 47, */ 14-1, 20UL*20UL*20UL*20UL*20UL*20UL*20UL*20UL*20UL*20UL*20UL*20UL*20UL*20UL},
151 { /* 102, 7, */ 14-1, 21UL*21UL*21UL*21UL*21UL*21UL*21UL*21UL*21UL*21UL*21UL*21UL*21UL*21UL},
152 { /* 775, 54, */ 14-1, 22UL*22UL*22UL*22UL*22UL*22UL*22UL*22UL*22UL*22UL*22UL*22UL*22UL*22UL},
153 { /* 382, 27, */ 14-1, 23UL*23UL*23UL*23UL*23UL*23UL*23UL*23UL*23UL*23UL*23UL*23UL*23UL*23UL},
154 { /* 1019, 73, */ 13-1, 24UL*24UL*24UL*24UL*24UL*24UL*24UL*24UL*24UL*24UL*24UL*24UL*24UL},
155 { /* 758, 55, */ 13-1, 25UL*25UL*25UL*25UL*25UL*25UL*25UL*25UL*25UL*25UL*25UL*25UL*25UL},
156 { /* 994, 73, */ 13-1, 26UL*26UL*26UL*26UL*26UL*26UL*26UL*26UL*26UL*26UL*26UL*26UL*26UL},
157 { /* 673, 50, */ 13-1, 27UL*27UL*27UL*27UL*27UL*27UL*27UL*27UL*27UL*27UL*27UL*27UL*27UL},
158 { /* 892, 67, */ 13-1, 28UL*28UL*28UL*28UL*28UL*28UL*28UL*28UL*28UL*28UL*28UL*28UL*28UL},
159 { /* 830, 63, */ 13-1, 29UL*29UL*29UL*29UL*29UL*29UL*29UL*29UL*29UL*29UL*29UL*29UL*29UL},
160 { /* 300, 23, */ 13-1, 30UL*30UL*30UL*30UL*30UL*30UL*30UL*30UL*30UL*30UL*30UL*30UL*30UL},
161 { /* 633, 49, */ 12-1, 31UL*31UL*31UL*31UL*31UL*31UL*31UL*31UL*31UL*31UL*31UL*31UL},
162 { /* 64, 5, */ 12-1, 32UL*32UL*32UL*32UL*32UL*32UL*32UL*32UL*32UL*32UL*32UL*32UL},
163 { /* 203, 16, */ 12-1, 33UL*33UL*33UL*33UL*33UL*33UL*33UL*33UL*33UL*33UL*33UL*33UL},
164 { /* 629, 50, */ 12-1, 34UL*34UL*34UL*34UL*34UL*34UL*34UL*34UL*34UL*34UL*34UL*34UL},
165 { /* 836, 67, */ 12-1, 35UL*35UL*35UL*35UL*35UL*35UL*35UL*35UL*35UL*35UL*35UL*35UL},
166 { /* 359, 29, */ 12-1, 36UL*36UL*36UL*36UL*36UL*36UL*36UL*36UL*36UL*36UL*36UL*36UL},
170 // Timing für Dezimal-Umwandlung einer Zahl mit N Digits = (N*32) Bits,
171 // auf einem i486 33 MHz unter Linux:
172 // N standard dnq(div) dnq(mul) combined
173 // 10 0.00031 0.00043 0.00059 0.00031
174 // 25 0.00103 0.00125 0.00178 0.00103
175 // 50 0.0030 0.0034 0.0051 0.0030
176 // 100 0.0100 0.0108 0.0155 0.0100
177 // 250 0.054 0.055 0.064 0.054
178 // 500 0.207 0.209 0.229 0.207
179 // 750 0.47 0.48 0.47 0.47
180 // 1000 0.81 0.81 0.86 0.81
181 // 1250 1.25 1.12 1.20 1.12
182 // 1500 1.81 1.60 1.64 1.61
183 // 1750 2.45 2.24 2.15 2.25
184 // 1940 3.01 3.03 3.12 2.80
185 // 2000 3.20 3.11 3.30 2.89
186 // 2500 5.00 4.11 4.38 3.91
187 // 3000 7.3 5.8 5.7 5.5
188 // 4000 13.0 12.4 12.9 9.7
189 // 5000 20.3 15.3 15.1 12.4
190 // 10000 81.4 57.8 56.4 32.5
193 // dnq(div) means divide-and-conquer using division by B at the topmost call,
195 // dnq(mul) means divide-and-conquer using multiplication by 1/B at the topmost
196 // call, threshold = 2050.
197 // combined means divide-and-conquer as long as length >= threshold.
198 const unsigned int cl_digits_div_threshold = 1015;
199 //#define MUL_REPLACES_DIV
200 const int cl_digits_algo = 1;
202 // Tabelle: enthält zu jeder Basis b (2 <= b <= 36)
203 // NULL oder einen Vektor von lazy berechneten b^(k*2^i) und 1/b^(k*2^i).
204 typedef struct cached_power_table_entry {
205 ALLOCATE_ANYWHERE(cached_power_table_entry)
206 cl_I base_pow; // 0 or b^(k*2^i)
207 #ifdef MUL_REPLACES_DIV
208 cl_I inv_base_pow; // if base_pow: floor(2^(2*integer_length(base_pow))/base_pow)
210 } cached_power_table_entry;
211 struct cached_power_table {
212 cached_power_table_entry element[30];
213 // Constructor and destructor - nothing special.
214 cached_power_table () {}
215 ~cached_power_table () {}
216 // Allocation and deallocation.
217 void* operator new (size_t size) { return cl_malloc_hook(size); }
218 void operator delete (void* ptr) { cl_free_hook(ptr); }
220 static cached_power_table* ctable [36-2+1] =
221 { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
222 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
223 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
224 NULL, NULL, NULL, NULL, NULL
226 static const cached_power_table_entry * cached_power (uintD base, uintL i)
227 { var cached_power_table* ptr;
228 if (!(ptr = ctable[base-2]))
229 { ctable[base-2] = ptr = new cached_power_table (); }
231 for (j = 0; j <= i; j++)
232 if (zerop(ptr->element[j].base_pow))
233 { // Compute b^(k*2^j) and its inverse.
235 (j==0 ? (cl_I)(unsigned long)(table[base-2].b_hoch_k)
236 : ptr->element[j-1].base_pow * ptr->element[j-1].base_pow
238 ptr->element[j].base_pow = x;
239 #ifdef MUL_REPLACES_DIV
240 ptr->element[j].inv_base_pow = floor1(ash(1,2*integer_length(x)),x);
243 return &ptr->element[i];
245 AT_DESTRUCTION(cached_power)
246 { for (var uintD base = 2; base <= 36; base++)
247 { var cached_power_table* ptr = ctable[base-2];
249 { delete ptr; ctable[base-2] = NULL; }
253 // like I_to_digits, except that the result has exactly erg_len characters.
254 static inline void I_to_digits_noshrink (const cl_I& X, uintD base, uintL erg_len, cl_digits* erg)
256 I_to_digits(X,base,erg);
257 if (erg->len > erg_len) cl_abort();
258 var uintL count = erg_len - erg->len;
260 { var uintB* ptr = erg->MSBptr;
261 do { *--ptr = '0'; } while (--count > 0);
262 erg->MSBptr = ptr; erg->len = erg->len;
266 void I_to_digits (const cl_I& X, uintD base, cl_digits* erg)
269 // Umwandlung ins Stellensystem der Basis b geht durch Umwandlung ins Stellen-
270 // system der Basis b^k (k>=1, b^k<2^intDsize, k maximal) vor sich.
271 // Aufsuchen von k und b^k aus einer Tabelle.
272 // Reduktion der UDS zu einer NUDS X.
273 // Falls X=0: die eine Ziffer 0.
275 // Dividiere X durch das Wort b^k,
276 // (Single-Precision-Division, vgl. UDS_DIVIDE mit n=1:
277 // r:=0, j:=m=Länge(X),
279 // j:=j-1, r:=r*beta+X[j], X[j]:=floor(r/b^k), r:=r-b^k*q[j].
281 // zerlege den Rest (mit k-1 Divisionen durch b) in k Ziffern, wandle diese
282 // Ziffern einzeln in Ascii um und lege sie an die DIGITS an.
283 // Teste auf Speicherüberlauf.
285 // Mache aus X wieder eine NUDS (maximal 1 Nulldigit streichen).
286 // Dies solange bis X=0.
287 // Streiche die führenden Nullen.
288 // Aufsuchen von k-1 und b^k aus der Tabelle:
289 var power_table_entry* tableptr = &table[base-2];
290 var uintC k_1 = tableptr->k_1; // k-1
291 var uintD b_hoch_k = tableptr->b_hoch_k; // b^k
292 var uintB* erg_ptr = erg->LSBptr;
293 #define next_digit(d) { *--erg_ptr = (d<10 ? '0'+d : 'A'-10+d); }
296 { next_digit(0); goto fertig; } // 0 -> eine Ziffer '0'
297 else if ((base & (base-1)) == 0)
298 { // Schneller Algorithmus für Zweierpotenzen
299 var const uintD* MSDptr;
301 var const uintD* LSDptr;
302 I_to_NDS_nocopy(X, MSDptr=,len=,LSDptr=,cl_false,);
303 var int b = (base==2 ? 1 : base==4 ? 2 : base==8 ? 3 : /*base==16*/ 4);
305 var int carrybits = 0;
307 { if (carrybits >= b)
308 { var uintD d = carry & (base-1);
310 carry = carry >> b; carrybits -= b;
313 { var uintD d = carry;
314 if (LSDptr != MSDptr)
315 { carry = lsprefnext(LSDptr);
316 d |= (carry << carrybits) & (base-1);
318 carry = carry >> (b-carrybits); carrybits = intDsize - (b-carrybits);
321 { next_digit(d); break; }
325 else if (fixnump(X) || TheBignum(X)->length < cl_digits_div_threshold
327 { // Standard-Algorithmus
332 I_to_NDS(X, MSDptr=,len=,LSDptr=);
333 // normalisiere zu einer NUDS:
334 if (mspref(MSDptr,0)==0) { msshrink(MSDptr); len--; }
336 { // Noch die NUDS MSDptr/len/.. mit len>0 abzuarbeiten.
337 // Single-Precision-Division durch b^k:
338 var uintD rest = divu_loop_msp(b_hoch_k,MSDptr,len);
339 // Zerlegen des Restes in seine k Ziffern:
340 var uintC count = k_1;
341 if ((intDsize>=11) || (count>0))
342 // (Bei intDsize>=11 ist wegen b<=36 zwangsläufig
343 // k = ceiling(intDsize*log(2)/log(b))-1 >= 2, also count = k_1 > 0.)
346 divuD((uintDD)rest,base,rest=,d=);
348 divuD(0,rest,base,rest=,d=);
352 until (--count == 0);
353 next_digit(rest); // letzte der k Ziffern ablegen
354 // Quotienten normalisieren (max. 1 Digit streichen):
355 if (mspref(MSDptr,0)==0) { msshrink(MSDptr); len--; if (len==0) break; }
358 { // Divide-and-conquer:
359 // Find largest i such that B = base^(k*2^i) satisfies B <= X.
360 // Divide by B: X = X1*B + X0. Convert X0 to string, fill up
361 // for k*2^i characters, convert X1 to string. (Have to convert
362 // X0 first because the conversion may temporarily prepend some
364 var uintL ilen_X = integer_length(X);
365 var const cached_power_table_entry * p;
369 { p = cached_power(base,i);
370 ilen_B = integer_length(p->base_pow);
371 if (2*ilen_B >= ilen_X) break;
372 // 2*ilen_B < ilen_X, so certainly B^2 < X, let's continue with i+1.
374 // 2*ilen_B >= ilen_X, implies X < 2*B^2.
375 // Of course also X >= B, implies ilen_X >= ilen_B.
376 #ifdef MUL_REPLACES_DIV
377 // Divide by B by computing
378 // q := floor((X * floor(2^ilen_X/B)) / 2^ilen_X).
379 // We have q <= floor(X/B) <= q+1, so we may have to increment q.
381 // floor(2^ilen_X/B) = floor(floor(2^(2*ilen_B)/B)/2^(2*ilen_B-ilen_X))
382 var cl_I q = (X * (p->inv_base_pow >> (2*ilen_B-ilen_X))) >> ilen_X;
383 var cl_I r = X - q * p->base_pow;
384 if (r < 0) cl_abort();
385 if (r >= p->base_pow)
386 { q = q+1; r = r - p->base_pow;
387 if (r >= p->base_pow) cl_abort();
390 var cl_I_div_t q_r = floor2(X,p->base_pow);
391 var const cl_I& q = q_r.quotient;
392 var const cl_I& r = q_r.remainder;
394 var const cl_I& X1 = q;
395 var const cl_I& X0 = r;
396 var uintL B_baselen = (uintL)(k_1+1)<<i;
397 I_to_digits_noshrink(X0,base,B_baselen,erg);
398 erg->LSBptr -= B_baselen;
399 I_to_digits(X1,base,erg);
400 erg->LSBptr += B_baselen;
401 erg_ptr = erg->MSBptr;
404 // Streiche führende Nullen:
405 while (*erg_ptr == '0') { erg_ptr++; }
407 erg->MSBptr = erg_ptr;
408 erg->len = erg->LSBptr - erg_ptr;
410 // Bit complexity (N := length(X)): O(log(N)*M(N)).