1 /********************************************************************/
2 /* */
3 /* big_rtl.c Functions for the built-in bigInteger support. */
4 /* Copyright (C) 1989 - 2019 Thomas Mertes */
5 /* */
6 /* This file is part of the Seed7 Runtime Library. */
7 /* */
8 /* The Seed7 Runtime Library is free software; you can */
9 /* redistribute it and/or modify it under the terms of the GNU */
10 /* Lesser General Public License as published by the Free Software */
11 /* Foundation; either version 2.1 of the License, or (at your */
12 /* option) any later version. */
13 /* */
14 /* The Seed7 Runtime Library is distributed in the hope that it */
15 /* will be useful, but WITHOUT ANY WARRANTY; without even the */
16 /* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
17 /* PURPOSE. See the GNU Lesser General Public License for more */
18 /* details. */
19 /* */
20 /* You should have received a copy of the GNU Lesser General */
21 /* Public License along with this program; if not, write to the */
22 /* Free Software Foundation, Inc., 51 Franklin Street, */
23 /* Fifth Floor, Boston, MA 02110-1301, USA. */
24 /* */
25 /* Module: Seed7 Runtime Library */
26 /* File: seed7/src/big_rtl.c */
27 /* Changes: 2005, 2006, 2008 - 2010, 2013 - 2019 Thomas Mertes */
28 /* Content: Functions for the built-in bigInteger support. */
29 /* */
30 /********************************************************************/
31
32 #define LOG_FUNCTIONS 0
33 #define VERBOSE_EXCEPTIONS 0
34
35 #include "version.h"
36
37 #if BIGINT_LIB == BIG_RTL_LIBRARY
38 #include "stdlib.h"
39 #include "stdio.h"
40 #include "string.h"
41 #include "limits.h"
42
43 #include "common.h"
44 #include "data_rtl.h"
45 #include "heaputl.h"
46 #include "striutl.h"
47 #include "int_rtl.h"
48 #include "rtl_err.h"
49
50 #undef EXTERN
51 #define EXTERN
52 #include "big_drv.h"
53
54
55 #define KARATSUBA_MULT_THRESHOLD 32
56 #define KARATSUBA_SQUARE_THRESHOLD 32
57 #define OCTAL_DIGIT_BITS 3
58
59
60 /* Defines to describe a bigdigit: */
61 /* BIGDIGIT_MASK All bits in a bigdigit are set. */
62 /* BIGDIGIT_SIGN The highest bit of a bigdigit is set. */
63 /* POWER_OF_10_IN_BIGDIGIT The biggest power of 10 which fits */
64 /* in a bigdigit. */
65 /* DECIMAL_DIGITS_IN_BIGDIGIT The number of zero digits in */
66 /* POWER_OF_10_IN_BIGDIGIT. */
67
68
69 #if BIGDIGIT_SIZE == 8
70
71 /* typedef uint8Type bigDigitType; */
72 typedef int8Type signedBigDigitType;
73 typedef uint16Type doubleBigDigitType;
74 typedef int16Type signedDoubleBigDigitType;
75 #define digitMostSignificantBit uint8MostSignificantBit
76 #define digitLeastSignificantBit uint8LeastSignificantBit
77 #define BIGDIGIT_MASK 0xFF
78 #define BIGDIGIT_SIGN 0x80
79 #define BIGDIGIT_SIZE_MASK 0x7
80 #define BIGDIGIT_LOG2_SIZE 3
81 #define POWER_OF_10_IN_BIGDIGIT 100
82 #define DECIMAL_DIGITS_IN_BIGDIGIT 2
83 #define POWER_OF_5_IN_BIGDIGIT 125
84 #define QUINARY_DIGITS_IN_BIGDIGIT 3
85 #define F_D_DIG(width) F_D8(width)
86 #define F_U_DIG(width) F_U8(width)
87 #define F_X_DIG(width) F_X8(width)
88 #define FMT_D_DIG FMT_D8
89 #define FMT_U_DIG FMT_U8
90 #define FMT_X_DIG FMT_X8
91 #define F_D_DIG2(width) F_D16(width)
92 #define F_U_DIG2(width) F_U16(width)
93 #define F_X_DIG2(width) F_X16(width)
94 #define FMT_D_DIG2 FMT_D16
95 #define FMT_U_DIG2 FMT_U16
96 #define FMT_X_DIG2 FMT_X16
97 static const bigDigitType powerOfRadixInBigdigit[] = {
98 /* 2 */ 128, 243, 64, 125, 216,
99 /* 7 */ 49, 64, 81, 100, 121,
100 /* 12 */ 144, 169, 196, 225, 16,
101 /* 17 */ 17, 18, 19, 20, 21,
102 /* 22 */ 22, 23, 24, 25, 26,
103 /* 27 */ 27, 28, 29, 30, 31,
104 /* 32 */ 32, 33, 34, 35, 36
105 };
106 static const uint8Type radixDigitsInBigdigit[] = {
107 /* 2 */ 7, 5, 3, 3, 3, 2, 2, 2, 2, 2,
108 /* 12 */ 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
109 /* 22 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
110 /* 32 */ 1, 1, 1, 1, 1
111 };
112
113 #elif BIGDIGIT_SIZE == 16
114
115 /* typedef uint16Type bigDigitType; */
116 typedef int16Type signedBigDigitType;
117 typedef uint32Type doubleBigDigitType;
118 typedef int32Type signedDoubleBigDigitType;
119 #define digitMostSignificantBit uint16MostSignificantBit
120 #define digitLeastSignificantBit uint16LeastSignificantBit
121 #define BIGDIGIT_MASK 0xFFFF
122 #define BIGDIGIT_SIGN 0x8000
123 #define BIGDIGIT_SIZE_MASK 0xF
124 #define BIGDIGIT_LOG2_SIZE 4
125 #define POWER_OF_10_IN_BIGDIGIT 10000
126 #define DECIMAL_DIGITS_IN_BIGDIGIT 4
127 #define POWER_OF_5_IN_BIGDIGIT 15625
128 #define QUINARY_DIGITS_IN_BIGDIGIT 6
129 #define F_D_DIG(width) F_D16(width)
130 #define F_U_DIG(width) F_U16(width)
131 #define F_X_DIG(width) F_X16(width)
132 #define FMT_D_DIG FMT_D16
133 #define FMT_U_DIG FMT_U16
134 #define FMT_X_DIG FMT_X16
135 #define F_D_DIG2(width) F_D32(width)
136 #define F_U_DIG2(width) F_U32(width)
137 #define F_X_DIG2(width) F_X32(width)
138 #define FMT_D_DIG2 FMT_D32
139 #define FMT_U_DIG2 FMT_U32
140 #define FMT_X_DIG2 FMT_X32
141 static const bigDigitType powerOfRadixInBigdigit[] = {
142 /* 2 */ 32768, 59049, 16384, 15625, 46656,
143 /* 7 */ 16807, 32768, 59049, 10000, 14641,
144 /* 12 */ 20736, 28561, 38416, 50625, 4096,
145 /* 17 */ 4913, 5832, 6859, 8000, 9261,
146 /* 22 */ 10648, 12167, 13824, 15625, 17576,
147 /* 27 */ 19683, 21952, 24389, 27000, 29791,
148 /* 32 */ 32768, 35937, 39304, 42875, 46656
149 };
150 static const uint8Type radixDigitsInBigdigit[] = {
151 /* 2 */ 15, 10, 7, 6, 6, 5, 5, 5, 4, 4,
152 /* 12 */ 4, 4, 4, 4, 3, 3, 3, 3, 3, 3,
153 /* 22 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
154 /* 32 */ 3, 3, 3, 3, 3
155 };
156
157 #elif BIGDIGIT_SIZE == 32
158
159 /* typedef uint32Type bigDigitType; */
160 typedef int32Type signedBigDigitType;
161 typedef uint64Type doubleBigDigitType;
162 typedef int64Type signedDoubleBigDigitType;
163 #define digitMostSignificantBit uint32MostSignificantBit
164 #define digitLeastSignificantBit uint32LeastSignificantBit
165 #define BIGDIGIT_MASK 0xFFFFFFFF
166 #define BIGDIGIT_SIGN 0x80000000
167 #define BIGDIGIT_SIZE_MASK 0x1F
168 #define BIGDIGIT_LOG2_SIZE 5
169 #define POWER_OF_10_IN_BIGDIGIT 1000000000
170 #define DECIMAL_DIGITS_IN_BIGDIGIT 9
171 #define POWER_OF_5_IN_BIGDIGIT 1220703125
172 #define QUINARY_DIGITS_IN_BIGDIGIT 13
173 #define F_D_DIG(width) F_D32(width)
174 #define F_U_DIG(width) F_U32(width)
175 #define F_X_DIG(width) F_X32(width)
176 #define FMT_D_DIG FMT_D32
177 #define FMT_U_DIG FMT_U32
178 #define FMT_X_DIG FMT_X32
179 #define F_D_DIG2(width) F_D64(width)
180 #define F_U_DIG2(width) F_U64(width)
181 #define F_X_DIG2(width) F_X64(width)
182 #define FMT_D_DIG2 FMT_D64
183 #define FMT_U_DIG2 FMT_U64
184 #define FMT_X_DIG2 FMT_X64
185 static const bigDigitType powerOfRadixInBigdigit[] = {
186 /* 2 */ 2147483648u, 3486784401u, 1073741824u, 1220703125u, 2176782336u,
187 /* 7 */ 1977326743u, 1073741824u, 3486784401u, 1000000000u, 2357947691u,
188 /* 12 */ 429981696u, 815730721u, 1475789056u, 2562890625u, 268435456u,
189 /* 17 */ 410338673u, 612220032u, 893871739u, 1280000000u, 1801088541u,
190 /* 22 */ 2494357888u, 3404825447u, 191102976u, 244140625u, 308915776u,
191 /* 27 */ 387420489u, 481890304u, 594823321u, 729000000u, 887503681u,
192 /* 32 */ 1073741824u, 1291467969u, 1544804416u, 1838265625u, 2176782336u
193 };
194 static const uint8Type radixDigitsInBigdigit[] = {
195 /* 2 */ 31, 20, 15, 13, 12, 11, 10, 10, 9, 9,
196 /* 12 */ 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
197 /* 22 */ 7, 7, 6, 6, 6, 6, 6, 6, 6, 6,
198 /* 32 */ 6, 6, 6, 6, 6
199 };
200
201 #endif
202
203
204 bigIntType *conversionDivisorCache[] = {
205 /* 0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
206 /* 10 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
207 /* 20 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
208 /* 30 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL
209 };
210
211 unsigned int conversionDivisorCacheSize[] = {
212 /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
213 /* 30 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
214 };
215
216
217 #define IS_NEGATIVE(digit) (((digit) & BIGDIGIT_SIGN) != 0)
218
219 static const unsigned int digit_value[] = {
220 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* Digits 0 - 9 */
221 36, 36, 36, 36, 36, 36, 36, /* Illegal digits */
222 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, /* Digits A - M */
223 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, /* Digits N - Z */
224 36, 36, 36, 36, 36, 36, /* Illegal digits */
225 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, /* Digits a - m */
226 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 /* Digits n - z */
227 };
228
229
230 #if DO_HEAP_STATISTIC
231 const size_t sizeof_bigDigitType = sizeof(bigDigitType);
232 const size_t sizeof_bigIntRecord = sizeof(bigIntRecord);
233 #endif
234
235
236 #define SIZ_RTLBIG(len) ((sizeof(bigIntRecord) - sizeof(bigDigitType)) + \
237 (len) * sizeof(bigDigitType))
238 #define MAX_BIG_LEN ((MAX_MEMSIZETYPE - sizeof(bigIntRecord) + \
239 sizeof(bigDigitType)) / sizeof(bigDigitType))
240
241 #if WITH_BIGINT_CAPACITY
242 #define HEAP_ALLOC_BIG(var,len) (ALLOC_HEAP(var, bigIntType, SIZ_RTLBIG(len))? \
243 ((var)->capacity = len, CNT(CNT1_BIG(len, SIZ_RTLBIG(len))) TRUE): \
244 FALSE)
245 #define HEAP_FREE_BIG(var,len) (CNT(CNT2_BIG(len, SIZ_RTLBIG(len))) \
246 FREE_HEAP(var, SIZ_RTLBIG(len)))
247
248 #define HEAP_REALLOC_BIG(v1,v2,l1,l2) if((v1=REALLOC_HEAP(v2, bigIntType, SIZ_RTLBIG(l2)))!=NULL) \
249 (v1)->capacity=l2;
250 #else
251 #define HEAP_ALLOC_BIG(var,len) (ALLOC_HEAP(var, bigIntType, SIZ_RTLBIG(len))? \
252 CNT(CNT1_BIG(len, SIZ_RTLBIG(len))) TRUE:FALSE)
253 #define HEAP_FREE_BIG(var,len) (CNT(CNT2_BIG(len, SIZ_RTLBIG(len))) \
254 FREE_HEAP(var, SIZ_RTLBIG(len)))
255
256 #define HEAP_REALLOC_BIG(v1,v2,l1,l2) v1=REALLOC_HEAP(v2, bigIntType, SIZ_RTLBIG(l2));
257 #endif
258 #define COUNT3_BIG(len1,len2) CNT3(CNT2_BIG(len1, SIZ_RTLBIG(len1)), \
259 CNT1_BIG(len2, SIZ_RTLBIG(len2)))
260
261 #if WITH_BIGINT_FREELIST
262 #if WITH_BIGINT_CAPACITY
263
264 #define BIG_FREELIST_ARRAY_SIZE 32
265
266 static freeListElemType flist[BIG_FREELIST_ARRAY_SIZE] = {
267 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
268 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
269 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
270 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
271 static unsigned int flist_allowed[BIG_FREELIST_ARRAY_SIZE] = {
272 0, 100, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
273 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20};
274
275 #define POP_BIG_OK(len) (len) < BIG_FREELIST_ARRAY_SIZE && flist[len] != NULL
276 #define PUSH_BIG_OK(var) (var)->capacity < BIG_FREELIST_ARRAY_SIZE && \
277 flist_allowed[(var)->capacity] > 0
278
279 #define POP_BIG(var,len) (var = (bigIntType) flist[len], flist[len] = flist[len]->next, \
280 flist_allowed[len]++, TRUE)
281 #define PUSH_BIG(var,len) {((freeListElemType) var)->next = flist[len]; \
282 flist[len] = (freeListElemType) var; flist_allowed[len]--; }
283
284 #define ALLOC_BIG_SIZE_OK(var,len) (POP_BIG_OK(len) ? POP_BIG(var, len) : \
285 HEAP_ALLOC_BIG(var, len))
286 #define ALLOC_BIG_CHECK_SIZE(var,len) (POP_BIG_OK(len) ? POP_BIG(var, len) : \
287 ((len)<=MAX_BIG_LEN?HEAP_ALLOC_BIG(var, len): \
288 (var=NULL, FALSE)))
289 #define FREE_BIG(var,len) if (PUSH_BIG_OK(var)) PUSH_BIG(var, (var)->capacity) else \
290 HEAP_FREE_BIG(var, (var)->capacity);
291
292 #else
293
294 static freeListElemType flist = NULL;
295 static unsigned int flist_allowed = 100;
296
297 #define POP_BIG_OK(len) (len) == 1 && flist != NULL
298 #define PUSH_BIG_OK(len) (len) == 1 && flist_allowed > 0
299
300 #define POP_BIG(var) (var = (bigIntType) flist, flist = flist->next, flist_allowed++, TRUE)
301 #define PUSH_BIG(var) {((freeListElemType) var)->next = flist; \
302 flist = (freeListElemType) var; flist_allowed--; }
303
304 #define ALLOC_BIG_SIZE_OK(var,len) (POP_BIG_OK(len) ? POP_BIG(var) : HEAP_ALLOC_BIG(var, len))
305 #define ALLOC_BIG_CHECK_SIZE(var,len) (POP_BIG_OK(len) ? POP_BIG(var) : \
306 ((len) <= MAX_BIG_LEN?HEAP_ALLOC_BIG(var, len): \
307 (var=NULL, FALSE)))
308 #define FREE_BIG(var,len) if (PUSH_BIG_OK(len)) PUSH_BIG(var) else HEAP_FREE_BIG(var, len);
309
310 #endif
311 #else
312
313 #define ALLOC_BIG_SIZE_OK(var,len) HEAP_ALLOC_BIG(var, len)
314 #define ALLOC_BIG_CHECK_SIZE(var,len) ((len) <= MAX_BIG_LEN?HEAP_ALLOC_BIG(var, len): \
315 (var=NULL, FALSE))
316 #define FREE_BIG(var,len) HEAP_FREE_BIG(var, len)
317
318 #endif
319
320 #define ALLOC_BIG(var,len) ALLOC_BIG_CHECK_SIZE(var, len)
321 #define REALLOC_BIG_SIZE_OK(v1,v2,l1,l2) HEAP_REALLOC_BIG(v1,v2,l1,l2)
322 #define REALLOC_BIG_CHECK_SIZE(v1,v2,l1,l2) if((l2) <= MAX_BIG_LEN) \
323 {HEAP_REALLOC_BIG(v1,v2,l1,l2)}else v1=NULL;
324
325
326 void bigAddAssign (bigIntType *const big_variable, const const_bigIntType delta);
327 intType bigLowestSetBit (const const_bigIntType big1);
328 void bigLShiftAssign (bigIntType *const big_variable, intType lshift);
329 bigIntType bigRem (const const_bigIntType dividend, const const_bigIntType divisor);
330 bigIntType bigRShift (const const_bigIntType big1, const intType rshift);
331 void bigRShiftAssign (bigIntType *const big_variable, intType rshift);
332 bigIntType bigSbtr (const const_bigIntType minuend, const const_bigIntType subtrahend);
333 void bigSbtrAssign (bigIntType *const big_variable, const const_bigIntType big2);
334 striType bigStr (const const_bigIntType big1);
335
336
337
338 /**
339 * Setup bigInteger computations.
340 * This function must be called before doing any bigInteger computations.
341 */
setupBig(void)342 void setupBig (void)
343
344 { /* setupBig */
345 } /* setupBig */
346
347
348
bigHexCStri(const const_bigIntType big1)349 cstriType bigHexCStri (const const_bigIntType big1)
350
351 {
352 /* Length of the hex prefix (16#): */
353 const memSizeType hexPrefixLen = STRLEN("16#");
354 /* Number of hex digits in a byte: */
355 const memSizeType hexDigitsInByte = 2;
356 memSizeType pos;
357 memSizeType digitPos;
358 memSizeType len;
359 const_cstriType stri_ptr;
360 cstriType buffer;
361 cstriType result;
362
363 /* bigHexCStri */
364 if (likely(big1 != NULL && big1->size > 0)) {
365 if (unlikely(big1->size > (MAX_CSTRI_LEN - hexPrefixLen) /
366 hexDigitsInByte / (BIGDIGIT_SIZE >> 3) ||
367 !ALLOC_CSTRI(result, big1->size * (BIGDIGIT_SIZE >> 3) *
368 hexDigitsInByte + hexPrefixLen))) {
369 raise_error(MEMORY_ERROR);
370 return NULL;
371 } else {
372 buffer = result;
373 memcpy(buffer, "16#", hexPrefixLen);
374 buffer += hexPrefixLen;
375 pos = big1->size - 1;
376 #if BIGDIGIT_SIZE == 8
377 sprintf(buffer, F_X_DIG(02), big1->bigdigits[pos]);
378 #elif BIGDIGIT_SIZE == 16
379 sprintf(buffer, F_X_DIG(04), big1->bigdigits[pos]);
380 #elif BIGDIGIT_SIZE == 32
381 sprintf(buffer, F_X_DIG(08), big1->bigdigits[pos]);
382 #endif
383 digitPos = 0;
384 if (IS_NEGATIVE(big1->bigdigits[pos])) {
385 while (digitPos < BIGDIGIT_SIZE >> 2 &&
386 memcmp(&buffer[digitPos], "ff", 2) == 0 &&
387 ((buffer[digitPos + 2] >= '8' && buffer[digitPos + 2] <= '9') ||
388 (buffer[digitPos + 2] >= 'a' && buffer[digitPos + 2] <= 'f'))) {
389 digitPos += 2;
390 } /* while */
391 } else {
392 while (digitPos < BIGDIGIT_SIZE >> 2 &&
393 memcmp(&buffer[digitPos], "00", 2) == 0 &&
394 buffer[digitPos + 2] >= '0' && buffer[digitPos + 2] <= '7') {
395 digitPos += 2;
396 } /* while */
397 } /* if */
398 len = (BIGDIGIT_SIZE >> 2) - digitPos;
399 memmove(buffer, &buffer[digitPos], len + 1);
400 buffer += len;
401 while (pos > 0) {
402 pos--;
403 #if BIGDIGIT_SIZE == 8
404 sprintf(buffer, F_X_DIG(02), big1->bigdigits[pos]);
405 #elif BIGDIGIT_SIZE == 16
406 sprintf(buffer, F_X_DIG(04), big1->bigdigits[pos]);
407 #elif BIGDIGIT_SIZE == 32
408 sprintf(buffer, F_X_DIG(08), big1->bigdigits[pos]);
409 #endif
410 buffer += (BIGDIGIT_SIZE >> 3) * hexDigitsInByte;
411 } /* while */
412 } /* if */
413 } else {
414 if (big1 == NULL) {
415 stri_ptr = " *NULL_BIGINT* ";
416 len = STRLEN(" *NULL_BIGINT* ");
417 } else {
418 stri_ptr = " *ZERO_SIZE_BIGINT* ";
419 len = STRLEN(" *ZERO_SIZE_BIGINT* ");
420 } /* if */
421 if (unlikely(!ALLOC_CSTRI(result, len))) {
422 raise_error(MEMORY_ERROR);
423 return NULL;
424 } else {
425 strcpy(result, stri_ptr);
426 } /* if */
427 } /* if */
428 return result;
429 } /* bigHexCStri */
430
431
432
433 /**
434 * Remove leading zero (or BIGDIGIT_MASK) digits from a signed big integer.
435 * @return the normalized big integer.
436 */
normalize(bigIntType big1)437 static bigIntType normalize (bigIntType big1)
438
439 {
440 memSizeType pos;
441 bigDigitType digit;
442
443 /* normalize */
444 pos = big1->size;
445 if (pos >= 2) {
446 pos--;
447 digit = big1->bigdigits[pos];
448 if (digit == BIGDIGIT_MASK) {
449 do {
450 pos--;
451 digit = big1->bigdigits[pos];
452 } while (pos > 0 && digit == BIGDIGIT_MASK);
453 if (!IS_NEGATIVE(digit)) {
454 pos++;
455 } /* if */
456 } else if (digit == 0) {
457 do {
458 pos--;
459 digit = big1->bigdigits[pos];
460 } while (pos > 0 && digit == 0);
461 if (IS_NEGATIVE(digit)) {
462 pos++;
463 } /* if */
464 } /* if */
465 pos++;
466 #ifdef NORMALIZE_DOES_RESIZE
467 if (big1->size != pos) {
468 bigIntType resized_big1;
469
470 REALLOC_BIG_SIZE_OK(resized_big1, big1, big1->size, pos);
471 /* Avoid a MEMORY_ERROR in the strange case */
472 /* if a 'realloc' which shrinks memory fails. */
473 if (likely(resized_big1 != NULL)) {
474 big1 = resized_big1;
475 } /* if */
476 COUNT3_BIG(big1->size, pos);
477 big1->size = pos;
478 } /* if */
479 #else
480 big1->size = pos;
481 #endif
482 } /* if */
483 return big1;
484 } /* normalize */
485
486
487
negate_positive_big(const bigIntType big1)488 static void negate_positive_big (const bigIntType big1)
489
490 {
491 memSizeType pos = 0;
492 doubleBigDigitType carry = 1;
493
494 /* negate_positive_big */
495 do {
496 carry += ~big1->bigdigits[pos] & BIGDIGIT_MASK;
497 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
498 carry >>= BIGDIGIT_SIZE;
499 pos++;
500 } while (pos < big1->size);
501 } /* negate_positive_big */
502
503
504
positive_copy_of_negative_big(const bigIntType dest,const const_bigIntType big1)505 static void positive_copy_of_negative_big (const bigIntType dest,
506 const const_bigIntType big1)
507
508 {
509 memSizeType pos = 0;
510 doubleBigDigitType carry = 1;
511
512 /* positive_copy_of_negative_big */
513 do {
514 carry += ~big1->bigdigits[pos] & BIGDIGIT_MASK;
515 dest->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
516 carry >>= BIGDIGIT_SIZE;
517 pos++;
518 } while (pos < big1->size);
519 if (unlikely(IS_NEGATIVE(dest->bigdigits[pos - 1]))) {
520 dest->bigdigits[pos] = 0;
521 pos++;
522 } /* if */
523 dest->size = pos;
524 } /* positive_copy_of_negative_big */
525
526
527
alloc_positive_copy_of_negative_big(const const_bigIntType big1)528 static bigIntType alloc_positive_copy_of_negative_big (const const_bigIntType big1)
529
530 {
531 memSizeType pos;
532 doubleBigDigitType carry = 1;
533 bigIntType result;
534
535 /* alloc_positive_copy_of_negative_big */
536 if (likely(ALLOC_BIG_SIZE_OK(result, big1->size))) {
537 pos = 0;
538 do {
539 carry += ~big1->bigdigits[pos] & BIGDIGIT_MASK;
540 result->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
541 carry >>= BIGDIGIT_SIZE;
542 pos++;
543 } while (pos < big1->size);
544 result->size = pos;
545 } /* if */
546 return result;
547 } /* alloc_positive_copy_of_negative_big */
548
549
550
551 /**
552 * Multiplies big1 by POWER_OF_10_IN_BIGDIGIT and adds carry to the product.
553 * The resulting sum is assigned to big1. This function works
554 * for unsigned big integers. It is assumed that big1 contains
555 * enough memory.
556 */
uBigMultByPowerOf10AndAdd(const bigIntType big1,doubleBigDigitType carry)557 static inline void uBigMultByPowerOf10AndAdd (const bigIntType big1, doubleBigDigitType carry)
558
559 {
560 memSizeType pos = 0;
561
562 /* uBigMultByPowerOf10AndAdd */
563 do {
564 carry += (doubleBigDigitType) big1->bigdigits[pos] * POWER_OF_10_IN_BIGDIGIT;
565 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
566 carry >>= BIGDIGIT_SIZE;
567 pos++;
568 } while (pos < big1->size);
569 if (carry != 0) {
570 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
571 big1->size++;
572 } /* if */
573 } /* uBigMultByPowerOf10AndAdd */
574
575
576
577 /**
578 * Multiplies big1 by a factor and adds carry to the product.
579 * The resulting sum is assigned to big1. This function works
580 * for unsigned big integers. It is assumed that big1 contains
581 * enough memory.
582 */
uBigMultiplyAndAdd(const bigIntType big1,bigDigitType factor,doubleBigDigitType carry)583 static inline void uBigMultiplyAndAdd (const bigIntType big1, bigDigitType factor,
584 doubleBigDigitType carry)
585
586 {
587 memSizeType pos = 0;
588
589 /* uBigMultiplyAndAdd */
590 do {
591 carry += (doubleBigDigitType) big1->bigdigits[pos] * factor;
592 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
593 carry >>= BIGDIGIT_SIZE;
594 pos++;
595 } while (pos < big1->size);
596 if (carry != 0) {
597 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
598 big1->size++;
599 } /* if */
600 } /* uBigMultiplyAndAdd */
601
602
603
604 /**
605 * Divides the unsigned big integer big1 by POWER_OF_10_IN_BIGDIGIT.
606 * The quotient is assigned to big1.
607 * @return the remainder of the unsigned big integer division.
608 */
uBigDivideByPowerOf10(const bigIntType big1)609 static inline bigDigitType uBigDivideByPowerOf10 (const bigIntType big1)
610
611 {
612 memSizeType pos;
613 doubleBigDigitType carry = 0;
614 bigDigitType bigdigit;
615
616 /* uBigDivideByPowerOf10 */
617 pos = big1->size;
618 do {
619 pos--;
620 carry <<= BIGDIGIT_SIZE;
621 carry += big1->bigdigits[pos];
622 bigdigit = (bigDigitType) (carry / POWER_OF_10_IN_BIGDIGIT);
623 #if POINTER_SIZE <= BIGDIGIT_SIZE
624 /* There is probably no machine instruction for division */
625 /* and remainder of doubleBigDigitType values available. */
626 /* To compute the remainder fast the % operator is avoided */
627 /* and the remainder is computed with a multiplication and */
628 /* a subtraction. The overflow in the multiplication can be */
629 /* ignored, since the result of the subtraction fits in the */
630 /* lower bigdigit of carry. The wrong bits in the higher */
631 /* bigdigit of carry are masked away. */
632 carry = (carry - bigdigit * POWER_OF_10_IN_BIGDIGIT) & BIGDIGIT_MASK;
633 #else
634 /* There is probably a machine instruction for division */
635 /* and remainder of doubleBigDigitType values available. */
636 /* In the optimal case quotient and remainder can be */
637 /* computed with one instruction. */
638 carry %= POWER_OF_10_IN_BIGDIGIT;
639 #endif
640 big1->bigdigits[pos] = bigdigit;
641 } while (pos > 0);
642 return (bigDigitType) (carry);
643 } /* uBigDivideByPowerOf10 */
644
645
646
647 /**
648 * Divides the unsigned big integer big1 by POWER_OF_5_IN_BIGDIGIT.
649 * The quotient is assigned to big1.
650 * @return the remainder of the unsigned big integer division.
651 */
uBigDivideByPowerOf5(const bigIntType big1)652 static inline void uBigDivideByPowerOf5 (const bigIntType big1)
653
654 {
655 memSizeType pos;
656 doubleBigDigitType carry = 0;
657 bigDigitType bigdigit;
658
659 /* uBigDivideByPowerOf5 */
660 pos = big1->size;
661 do {
662 pos--;
663 carry <<= BIGDIGIT_SIZE;
664 carry += big1->bigdigits[pos];
665 bigdigit = (bigDigitType) (carry / POWER_OF_5_IN_BIGDIGIT);
666 #if POINTER_SIZE <= BIGDIGIT_SIZE
667 /* There is probably no machine instruction for division */
668 /* and remainder of doubleBigDigitType values available. */
669 /* To compute the remainder fast the % operator is avoided */
670 /* and the remainder is computed with a multiplication and */
671 /* a subtraction. The overflow in the multiplication can be */
672 /* ignored, since the result of the subtraction fits in the */
673 /* lower bigdigit of carry. The wrong bits in the higher */
674 /* bigdigit of carry are masked away. */
675 carry = (carry - bigdigit * POWER_OF_5_IN_BIGDIGIT) & BIGDIGIT_MASK;
676 #else
677 /* There is probably a machine instruction for division */
678 /* and remainder of doubleBigDigitType values available. */
679 /* In the optimal case quotient and remainder can be */
680 /* computed with one instruction. */
681 carry %= POWER_OF_5_IN_BIGDIGIT;
682 #endif
683 big1->bigdigits[pos] = bigdigit;
684 } while (pos > 0);
685 } /* uBigDivideByPowerOf5 */
686
687
688
689 /**
690 * Divides the unsigned big integer big1 by divisor_digit.
691 * The quotient is assigned to big1.
692 * @return the remainder of the unsigned big integer division.
693 */
uBigDivideByDigit(const bigIntType big1,const bigDigitType divisor_digit)694 static inline bigDigitType uBigDivideByDigit (const bigIntType big1,
695 const bigDigitType divisor_digit)
696
697 {
698 memSizeType pos;
699 doubleBigDigitType carry = 0;
700 bigDigitType bigdigit;
701
702 /* uBigDivideByDigit */
703 pos = big1->size;
704 do {
705 pos--;
706 carry <<= BIGDIGIT_SIZE;
707 carry += big1->bigdigits[pos];
708 bigdigit = (bigDigitType) (carry / divisor_digit);
709 #if POINTER_SIZE <= BIGDIGIT_SIZE
710 /* There is probably no machine instruction for division */
711 /* and remainder of doubleBigDigitType values available. */
712 /* To compute the remainder fast the % operator is avoided */
713 /* and the remainder is computed with a multiplication and */
714 /* a subtraction. The overflow in the multiplication can be */
715 /* ignored, since the result of the subtraction fits in the */
716 /* lower bigdigit of carry. The wrong bits in the higher */
717 /* bigdigit of carry are masked away. */
718 carry = (carry - bigdigit * divisor_digit) & BIGDIGIT_MASK;
719 #else
720 /* There is probably a machine instruction for division */
721 /* and remainder of doubleBigDigitType values available. */
722 /* In the optimal case quotient and remainder can be */
723 /* computed with one instruction. */
724 carry %= divisor_digit;
725 #endif
726 big1->bigdigits[pos] = bigdigit;
727 } while (pos > 0);
728 return (bigDigitType) (carry);
729 } /* uBigDivideByDigit */
730
731
732
733 /**
734 * Convert a numeric string, with a specified radix, to a 'bigInteger'.
735 * The numeric string must contain the representation of an integer
736 * in the specified radix. It consists of an optional + or - sign,
737 * followed by a sequence of digits in the specified radix. Digit values
738 * from 10 upward can be encoded with upper or lower case letters.
739 * E.g.: 10 can be encoded with A or a, 11 with B or b, etc. Other
740 * characters as well as leading or trailing whitespace characters
741 * are not allowed. The radix of the conversion is a power of two and
742 * it is specified indirectly with the parameter shift.
743 * @param stri Numeric string with integer in the specified radix.
744 * @param shift Logarithm (log2) of the specified radix.
745 * @return the 'bigInteger' result of the conversion.
746 * @exception RANGE_ERROR If the string does not contain an integer
747 * literal with the specified base.
748 * @exception MEMORY_ERROR Not enough memory to represent the result.
749 */
bigParseBasedPow2(const const_striType stri,unsigned int shift)750 static bigIntType bigParseBasedPow2 (const const_striType stri, unsigned int shift)
751
752 {
753 memSizeType mostSignificantDigitPos = 0;
754 boolType negative;
755 memSizeType bits_necessary;
756 boolType okay;
757 memSizeType charPos;
758 strElemType digit;
759 unsigned int base;
760 unsigned int digitval;
761 memSizeType bigDigitPos;
762 doubleBigDigitType bigDigit;
763 unsigned int bigDigitShift;
764 memSizeType result_size;
765 bigIntType result;
766
767 /* bigParseBasedPow2 */
768 logFunction(printf("bigParseBasedPow2(\"%s\", %u)\n",
769 striAsUnquotedCStri(stri), shift););
770 if (likely(stri->size != 0)) {
771 if (stri->mem[0] == ((strElemType) '-')) {
772 negative = TRUE;
773 mostSignificantDigitPos++;
774 } else {
775 if (stri->mem[0] == ((strElemType) '+')) {
776 mostSignificantDigitPos++;
777 } /* if */
778 negative = FALSE;
779 } /* if */
780 } /* if */
781 /* printf("mostSignificantDigitPos: " FMT_U_MEM "\n", mostSignificantDigitPos); */
782 if (unlikely(mostSignificantDigitPos >= stri->size)) {
783 logError(printf("bigParseBasedPow2(\"%s\", %u): "
784 "Digit missing.\n",
785 striAsUnquotedCStri(stri), shift););
786 raise_error(RANGE_ERROR);
787 result = NULL;
788 } else if (unlikely(stri->size - mostSignificantDigitPos >
789 MAX_MEMSIZETYPE / (memSizeType) shift)) {
790 raise_error(MEMORY_ERROR);
791 result = NULL;
792 } else {
793 base = (unsigned int) 1 << shift;
794 /* Compute the number of bits necessary: */
795 bits_necessary = (stri->size - mostSignificantDigitPos) * (memSizeType) shift;
796 /* printf("bits_necessary: " FMT_U_MEM "\n", bits_necessary); */
797 /* Compute the number of bigDigits: */
798 result_size = (bits_necessary - 1) / BIGDIGIT_SIZE + 1;
799 if ((bits_necessary & BIGDIGIT_SIZE_MASK) == 0) {
800 digit = stri->mem[mostSignificantDigitPos];
801 if (digit >= '0' && digit <= 'z') {
802 digitval = digit_value[digit - (strElemType) '0'];
803 if (digitval < base &&
804 (digitval >> (shift - 1) & 1) == 1) {
805 /* The highest bit of the most significant digit is set. */
806 result_size++;
807 } /* if */
808 } /* if */
809 } /* if */
810 /* printf("result_size: " FMT_U_MEM "\n", result_size); */
811 if (unlikely(!ALLOC_BIG(result, result_size))) {
812 raise_error(MEMORY_ERROR);
813 } else {
814 okay = TRUE;
815 bigDigit = 0;
816 bigDigitPos = 0;
817 bigDigitShift = 0;
818 for (charPos = stri->size; charPos > mostSignificantDigitPos && okay; charPos--) {
819 digit = stri->mem[charPos - 1];
820 if (likely(digit >= '0' && digit <= 'z')) {
821 digitval = digit_value[digit - (strElemType) '0'];
822 if (likely(digitval < base)) {
823 bigDigit |= (doubleBigDigitType) digitval << bigDigitShift;
824 } else {
825 okay = FALSE;
826 } /* if */
827 } else {
828 okay = FALSE;
829 } /* if */
830 bigDigitShift += shift;
831 if (bigDigitShift >= BIGDIGIT_SIZE) {
832 /* printf("result->bigdigits[" FMT_U_MEM "] = " F_X_DIG(08) "\n",
833 bigDigitPos, (bigDigitType) (bigDigit & BIGDIGIT_MASK)); */
834 result->bigdigits[bigDigitPos] = (bigDigitType) (bigDigit & BIGDIGIT_MASK);
835 bigDigitPos++;
836 bigDigit >>= BIGDIGIT_SIZE;
837 bigDigitShift -= BIGDIGIT_SIZE;
838 } /* if */
839 } /* for */
840 if (unlikely(!okay)) {
841 FREE_BIG(result, result_size);
842 logError(printf("bigParseBasedPow2(\"%s\", %u): "
843 "Illegal digit.\n",
844 striAsUnquotedCStri(stri), shift););
845 raise_error(RANGE_ERROR);
846 result = NULL;
847 } else {
848 result->size = result_size;
849 while (bigDigitPos < result_size) {
850 /* printf("result->bigdigits[" FMT_U_MEM "] = " F_X_DIG(08) "\n",
851 bigDigitPos, (bigDigitType) (bigDigit & BIGDIGIT_MASK)); */
852 result->bigdigits[bigDigitPos] = (bigDigitType) (bigDigit & BIGDIGIT_MASK);
853 bigDigitPos++;
854 bigDigit >>= BIGDIGIT_SIZE;
855 } /* while */
856 if (negative) {
857 negate_positive_big(result);
858 } /* if */
859 result = normalize(result);
860 } /* if */
861 } /* if */
862 } /* if */
863 logFunction(printf("bigParseBasedPow2 --> %s\n", bigHexCStri(result)););
864 return result;
865 } /* bigParseBasedPow2 */
866
867
868
869 /**
870 * Convert a numeric string, with a specified radix, to a 'bigInteger'.
871 * The numeric string must contain the representation of an integer
872 * in the specified radix. It consists of an optional + or - sign,
873 * followed by a sequence of digits in the specified radix. Digit values
874 * from 10 upward can be encoded with upper or lower case letters.
875 * E.g.: 10 can be encoded with A or a, 11 with B or b, etc. Other
876 * characters as well as leading or trailing whitespace characters
877 * are not allowed.
878 * @param stri Numeric string with integer in the specified radix.
879 * @param base Radix of the integer in the 'stri' parameter.
880 * @return the 'bigInteger' result of the conversion.
881 * @exception RANGE_ERROR If base < 2 or base > 36 holds or
882 * the string does not contain an integer
883 * literal with the specified base.
884 * @exception MEMORY_ERROR Not enough memory to represent the result.
885 */
bigParseBased2To36(const const_striType stri,unsigned int base)886 static bigIntType bigParseBased2To36 (const const_striType stri, unsigned int base)
887
888 {
889 boolType okay;
890 boolType negative;
891 memSizeType position = 0;
892 uint8Type based_digit_size;
893 uint8Type based_digits_in_bigdigit;
894 bigDigitType power_of_base_in_bigdigit;
895 memSizeType limit;
896 strElemType digit;
897 unsigned int digitval;
898 bigDigitType bigDigit;
899 memSizeType result_size;
900 bigIntType result;
901
902 /* bigParseBased2To36 */
903 logFunction(printf("bigParseBased2To36(\"%s\", %u)\n",
904 striAsUnquotedCStri(stri), base););
905 if (likely(stri->size != 0)) {
906 if (stri->mem[0] == ((strElemType) '-')) {
907 negative = TRUE;
908 position++;
909 } else {
910 if (stri->mem[0] == ((strElemType) '+')) {
911 position++;
912 } /* if */
913 negative = FALSE;
914 } /* if */
915 } /* if */
916 /* printf("position: " FMT_U_MEM "\n", position); */
917 if (unlikely(position >= stri->size)) {
918 logError(printf("bigParseBased2To36(\"%s\", %u): "
919 "Digit missing.\n",
920 striAsUnquotedCStri(stri), base););
921 raise_error(RANGE_ERROR);
922 result = NULL;
923 } else if (unlikely(stri->size > MAX_MEMSIZETYPE / 6)) {
924 raise_error(MEMORY_ERROR);
925 result = NULL;
926 } else {
927 based_digit_size = (uint8Type) (uint8MostSignificantBit((uint8Type) (base - 1)) + 1);
928 /* Estimate the number of bits necessary: */
929 result_size = stri->size * (memSizeType) based_digit_size;
930 /* Compute the number of bigDigits: */
931 result_size = result_size / BIGDIGIT_SIZE + 1;
932 if (unlikely(!ALLOC_BIG(result, result_size))) {
933 raise_error(MEMORY_ERROR);
934 } else {
935 result->size = 1;
936 result->bigdigits[0] = 0;
937 okay = TRUE;
938 based_digits_in_bigdigit = radixDigitsInBigdigit[base - 2];
939 power_of_base_in_bigdigit = powerOfRadixInBigdigit[base - 2];
940 limit = (stri->size - position - 1) % based_digits_in_bigdigit + position + 1;
941 do {
942 bigDigit = 0;
943 while (position < limit && okay) {
944 digit = stri->mem[position];
945 if (likely(digit >= '0' && digit <= 'z')) {
946 digitval = digit_value[digit - (strElemType) '0'];
947 if (likely(digitval < base)) {
948 bigDigit = (bigDigitType) base * bigDigit + digitval;
949 } else {
950 okay = FALSE;
951 } /* if */
952 } else {
953 okay = FALSE;
954 } /* if */
955 position++;
956 } /* while */
957 uBigMultiplyAndAdd(result, power_of_base_in_bigdigit, (doubleBigDigitType) bigDigit);
958 limit += based_digits_in_bigdigit;
959 } while (position < stri->size && okay);
960 if (likely(okay)) {
961 memset(&result->bigdigits[result->size], 0,
962 (size_t) (result_size - result->size) * sizeof(bigDigitType));
963 result->size = result_size;
964 if (negative) {
965 negate_positive_big(result);
966 } /* if */
967 result = normalize(result);
968 } else {
969 FREE_BIG(result, result_size);
970 logError(printf("bigParseBased2To36(\"%s\", %u): "
971 "Illegal digit.\n",
972 striAsUnquotedCStri(stri), base););
973 raise_error(RANGE_ERROR);
974 result = NULL;
975 } /* if */
976 } /* if */
977 } /* if */
978 logFunction(printf("bigParseBased2To36 --> %s\n", bigHexCStri(result)););
979 return result;
980 } /* bigParseBased2To36 */
981
982
983
984 /**
985 * Computes base ** (2 ** exponent) to be used as conversion divisor.
986 * The function uses a cache to avoid a recomputation.
987 * The result is used by binaryToStri and binaryRadix2To36 as
988 * divisor. The functions binaryToStri and binaryRadix2To36 use
989 * the binary algorithm to convert a bigInteger to a string.
990 * @return base ** (2 ** exponent).
991 */
getConversionDivisor(unsigned int base,unsigned int exponent)992 static bigIntType getConversionDivisor (unsigned int base, unsigned int exponent)
993
994 {
995 bigIntType *divisorCache;
996 unsigned int size;
997 unsigned int pos;
998 bigIntType divisor;
999
1000 /* getConversionDivisor */
1001 logFunction(printf("getConversionDivisor(%u, %u)\n", base, exponent););
1002 divisorCache = conversionDivisorCache[base];
1003 size = conversionDivisorCacheSize[base];
1004 if (exponent < size) {
1005 divisor = divisorCache[exponent];
1006 } else {
1007 divisorCache = (bigIntType *) realloc(divisorCache,
1008 (exponent + 1) * sizeof(bigIntType));
1009 if (unlikely(divisorCache == NULL)) {
1010 raise_error(MEMORY_ERROR);
1011 divisor = NULL;
1012 } else {
1013 if (size == 0) {
1014 divisorCache[0] = bigFromUInt32(base);
1015 size = 1;
1016 } /* if */
1017 for (pos = size; pos <= exponent; ++pos) {
1018 divisorCache[pos] = bigSquare(divisorCache[pos - 1]);
1019 } /* for */
1020 conversionDivisorCache[base] = divisorCache;
1021 conversionDivisorCacheSize[base] = exponent + 1;
1022 divisor = divisorCache[exponent];
1023 } /* if */
1024 } /* if */
1025 logFunction(printf("getConversionDivisor --> %s\n", bigHexCStri(divisor)););
1026 return divisor;
1027 } /* getConversionDivisor */
1028
1029
1030
basicToStri(const bigIntType unsignedBig,striType buffer,memSizeType pos)1031 static memSizeType basicToStri (const bigIntType unsignedBig,
1032 striType buffer, memSizeType pos)
1033
1034 {
1035 bigDigitType digit;
1036 int digit_pos;
1037
1038 /* basicToStri */
1039 logFunction(printf("basicToStri(%s, *, " FMT_U_MEM ")\n",
1040 bigHexCStri(unsignedBig), pos););
1041 do {
1042 digit = uBigDivideByPowerOf10(unsignedBig);
1043 /* printf("unsignedBig->size=" FMT_U_MEM ", digit=" FMT_U_DIG "\n",
1044 unsignedBig->size, digit); */
1045 if (unsignedBig->bigdigits[unsignedBig->size - 1] == 0) {
1046 unsignedBig->size--;
1047 } /* if */
1048 if (unsignedBig->size > 1 || unsignedBig->bigdigits[0] != 0) {
1049 for (digit_pos = DECIMAL_DIGITS_IN_BIGDIGIT;
1050 digit_pos != 0; digit_pos--) {
1051 buffer->mem[pos] = '0' + digit % 10;
1052 digit /= 10;
1053 pos--;
1054 } /* for */
1055 } else {
1056 do {
1057 buffer->mem[pos] = '0' + digit % 10;
1058 digit /= 10;
1059 pos--;
1060 } while (digit != 0);
1061 } /* if */
1062 } while (unsignedBig->size > 1 || unsignedBig->bigdigits[0] != 0);
1063 logFunction(printf("basicToStri --> " FMT_U_MEM "\n", pos););
1064 return pos;
1065 } /* basicToStri */
1066
1067
1068
binaryToStri(bigIntType unsignedBig,striType buffer,unsigned int exponent,boolType zeroPad,memSizeType pos)1069 static memSizeType binaryToStri (bigIntType unsignedBig, striType buffer,
1070 unsigned int exponent, boolType zeroPad, memSizeType pos)
1071
1072 {
1073 bigIntType divisor;
1074 bigIntType quotient;
1075 bigIntType remainder;
1076 memSizeType endPos;
1077
1078 /* binaryToStri */
1079 logFunction(printf("binaryToStri(%s, *, %u, %d, " FMT_U_MEM ")\n",
1080 bigHexCStri(unsignedBig), exponent, zeroPad, pos););
1081 if (exponent > 8) {
1082 exponent--;
1083 divisor = getConversionDivisor(10, exponent);
1084 if (divisor != NULL) {
1085 quotient = bigDivRem(unsignedBig, divisor, &remainder);
1086 if (quotient != NULL) {
1087 if (zeroPad || (quotient->size > 1 || quotient->bigdigits[0] != 0)) {
1088 pos = binaryToStri(remainder, buffer, exponent, TRUE, pos);
1089 pos = binaryToStri(quotient, buffer, exponent, zeroPad, pos);
1090 } else {
1091 pos = binaryToStri(remainder, buffer, exponent, FALSE, pos);
1092 } /* if */
1093 FREE_BIG(remainder, remainder->size);
1094 FREE_BIG(quotient, quotient->size);
1095 } /* if */
1096 } /* if */
1097 } else {
1098 endPos = pos;
1099 pos = basicToStri(unsignedBig, buffer, pos);
1100 if (zeroPad) {
1101 /* printf(FMT_U_MEM " " FMT_U_MEM " " FMT_U_MEM
1102 " insert " FMT_U_MEM " zero digits.\n",
1103 pos, endPos, (memSizeType) 1 << exponent,
1104 pos - (endPos - ((memSizeType) 1 << exponent))); */
1105 endPos -= (memSizeType) 1 << exponent;
1106 while (pos > endPos) {
1107 buffer->mem[pos] = '0';
1108 pos--;
1109 } /* while */
1110 } /* if */
1111 } /* if */
1112 logFunction(printf("binaryToStri --> " FMT_U_MEM "\n", pos););
1113 return pos;
1114 } /* binaryToStri */
1115
1116
1117
basicRadix2To36(const bigIntType unsignedBig,striType buffer,unsigned int base,const const_ustriType digits,memSizeType pos)1118 static memSizeType basicRadix2To36 (const bigIntType unsignedBig,
1119 striType buffer, unsigned int base, const const_ustriType digits,
1120 memSizeType pos)
1121
1122 {
1123 bigDigitType divisor_digit;
1124 uint8Type digits_in_bigdigit;
1125 bigDigitType digit;
1126 int digit_pos;
1127
1128 /* basicRadix2To36 */
1129 logFunction(printf("basicRadix2To36(%s, *, %u, *, " FMT_U_MEM ")\n",
1130 bigHexCStri(unsignedBig), base, pos););
1131 divisor_digit = powerOfRadixInBigdigit[base - 2];
1132 /* printf("divisor_digit: " FMT_U_DIG "\n", divisor_digit); */
1133 digits_in_bigdigit = radixDigitsInBigdigit[base - 2];
1134 /* printf("digits_in_bigdigit: %hd\n", digits_in_bigdigit); */
1135 do {
1136 digit = uBigDivideByDigit(unsignedBig, divisor_digit);
1137 /* printf("unsignedBig->size=" FMT_U_MEM ", digit=" FMT_U_DIG "\n",
1138 unsignedBig->size, digit); */
1139 if (unsignedBig->bigdigits[unsignedBig->size - 1] == 0) {
1140 unsignedBig->size--;
1141 } /* if */
1142 if (unsignedBig->size > 1 || unsignedBig->bigdigits[0] != 0) {
1143 for (digit_pos = digits_in_bigdigit;
1144 digit_pos != 0; digit_pos--) {
1145 buffer->mem[pos] = (strElemType) (digits[digit % base]);
1146 digit /= base;
1147 pos--;
1148 } /* for */
1149 } else {
1150 do {
1151 buffer->mem[pos] = (strElemType) (digits[digit % base]);
1152 digit /= base;
1153 pos--;
1154 } while (digit != 0);
1155 } /* if */
1156 } while (unsignedBig->size > 1 || unsignedBig->bigdigits[0] != 0);
1157 logFunction(printf("basicRadix2To36 --> " FMT_U_MEM "\n", pos););
1158 return pos;
1159 } /* basicRadix2To36 */
1160
1161
1162
binaryRadix2To36(bigIntType unsignedBig,striType buffer,unsigned int base,const const_ustriType digits,unsigned int exponent,boolType zeroPad,memSizeType pos)1163 static memSizeType binaryRadix2To36 (bigIntType unsignedBig,
1164 striType buffer, unsigned int base, const const_ustriType digits,
1165 unsigned int exponent, boolType zeroPad, memSizeType pos)
1166
1167 {
1168 bigIntType divisor;
1169 bigIntType quotient;
1170 bigIntType remainder;
1171 memSizeType endPos;
1172
1173 /* binaryRadix2To36 */
1174 logFunction(printf("binaryRadix2To36(%s, *, %u, *, %u, %u, "
1175 FMT_U_MEM ")\n", bigHexCStri(unsignedBig),
1176 base, exponent, zeroPad, pos););
1177 if (exponent > 8) {
1178 exponent--;
1179 divisor = getConversionDivisor(base, exponent);
1180 if (divisor != NULL) {
1181 quotient = bigDivRem(unsignedBig, divisor, &remainder);
1182 if (quotient != NULL) {
1183 if (zeroPad || (quotient->size > 1 || quotient->bigdigits[0] != 0)) {
1184 pos = binaryRadix2To36(remainder, buffer, base, digits,
1185 exponent, TRUE, pos);
1186 pos = binaryRadix2To36(quotient, buffer, base, digits,
1187 exponent, zeroPad, pos);
1188 } else {
1189 pos = binaryRadix2To36(remainder, buffer, base, digits,
1190 exponent, FALSE, pos);
1191 } /* if */
1192 FREE_BIG(remainder, remainder->size);
1193 FREE_BIG(quotient, quotient->size);
1194 } /* if */
1195 } /* if */
1196 } else {
1197 endPos = pos;
1198 pos = basicRadix2To36(unsignedBig, buffer, base, digits, pos);
1199 if (zeroPad) {
1200 /* printf(FMT_U_MEM " " FMT_U_MEM " " FMT_U_MEM
1201 " insert " FMT_U_MEM " zero digits.\n",
1202 pos, endPos, (memSizeType) 1 << exponent,
1203 pos - (endPos - ((memSizeType) 1 << exponent))); */
1204 endPos -= (memSizeType) 1 << exponent;
1205 while (pos > endPos) {
1206 buffer->mem[pos] = '0';
1207 pos--;
1208 } /* while */
1209 } /* if */
1210 } /* if */
1211 logFunction(printf("binaryRadix2To36 --> " FMT_U_MEM "\n", pos););
1212 return pos;
1213 } /* binaryRadix2To36 */
1214
1215
1216
1217 /**
1218 * Convert a big integer number to a string using a radix.
1219 * The conversion uses the numeral system with the specified base.
1220 * The base is a power of two and it is specified indirectly with
1221 * shift and mask. Digit values from 10 upward are encoded with
1222 * letters.
1223 * @param big1 BigInteger number to be converted.
1224 * @param shift Logarithm (log2) of the base (=number of bits in mask).
1225 * @param mask Mask to get the bits of a digit (equivalent to base-1).
1226 * @param upperCase Decides about the letter case.
1227 * @return the string result of the conversion.
1228 * @exception MEMORY_ERROR Not enough memory to represent the result.
1229 */
bigRadixPow2(const const_bigIntType big1,unsigned int shift,bigDigitType mask,boolType upperCase)1230 static striType bigRadixPow2 (const const_bigIntType big1, unsigned int shift,
1231 bigDigitType mask, boolType upperCase)
1232
1233 {
1234 const_bigIntType unsigned_big;
1235 memSizeType unsigned_size;
1236 doubleBigDigitType unsigned_digit;
1237 boolType negative;
1238 unsigned int most_significant;
1239 unsigned int digit_shift;
1240 memSizeType digit_index;
1241 const_ustriType digits;
1242 memSizeType pos;
1243 memSizeType result_size;
1244 striType result;
1245
1246 /* bigRadixPow2 */
1247 logFunction(printf("bigRadixPow2(%s, %u, " FMT_X_DIG ", %d)\n",
1248 bigHexCStri(big1), shift, mask, upperCase););
1249 negative = IS_NEGATIVE(big1->bigdigits[big1->size - 1]);
1250 if (negative) {
1251 unsigned_big = alloc_positive_copy_of_negative_big(big1);
1252 } else {
1253 unsigned_big = big1;
1254 } /* if */
1255 if (unlikely(unsigned_big == NULL)) {
1256 raise_error(MEMORY_ERROR);
1257 result = NULL;
1258 } else {
1259 unsigned_size = unsigned_big->size;
1260 /* Unsigned_size is reduced to avoid a leading zero digit. */
1261 /* Except for the value 0 unsigned_big has no leading zero digit. */
1262 while (unsigned_size > 1 && unsigned_big->bigdigits[unsigned_size - 1] == 0) {
1263 unsigned_size--;
1264 } /* while */
1265 if (unlikely((MAX_STRI_LEN <= (MAX_MEMSIZETYPE - 1) / shift +
1266 (unsigned int) negative + 1 &&
1267 unsigned_size > ((MAX_STRI_LEN - (unsigned int) negative - 1) *
1268 shift + 1) / BIGDIGIT_SIZE) ||
1269 unsigned_size > MAX_MEMSIZETYPE / BIGDIGIT_SIZE)) {
1270 if (unsigned_big != big1) {
1271 FREE_BIG(unsigned_big, unsigned_big->size);
1272 } /* if */
1273 raise_error(MEMORY_ERROR);
1274 result = NULL;
1275 } else {
1276 if (unsigned_size == 1 && unsigned_big->bigdigits[0] == 0) {
1277 /* The size of zero is always 1. */
1278 result_size = 1;
1279 } else {
1280 /* The size of the result is computed by computing */
1281 /* the number of radix digits plus one optional */
1282 /* character for the sign. */
1283 result_size = (unsigned_size * BIGDIGIT_SIZE - 1) / shift + (unsigned int) negative + 1;
1284 most_significant = (unsigned int)
1285 digitMostSignificantBit(unsigned_big->bigdigits[unsigned_size - 1]);
1286 digit_shift = (unsigned int) (BIGDIGIT_SIZE - (unsigned_size * BIGDIGIT_SIZE) % shift);
1287 if (most_significant < digit_shift) {
1288 /* Reduce result_size because of leading zero digits. */
1289 result_size -= (digit_shift - most_significant - 1) / shift;
1290 if (digit_shift != BIGDIGIT_SIZE) {
1291 result_size--;
1292 } /* if */
1293 } /* if */
1294 } /* if */
1295 /* printf("result_size: " FMT_U_MEM "\n", result_size); */
1296 if (unlikely(!ALLOC_STRI_SIZE_OK(result, result_size))) {
1297 if (unsigned_big != big1) {
1298 FREE_BIG(unsigned_big, unsigned_big->size);
1299 } /* if */
1300 raise_error(MEMORY_ERROR);
1301 result = NULL;
1302 } else {
1303 digits = digitTable[upperCase];
1304 pos = result_size;
1305 unsigned_digit = unsigned_big->bigdigits[0];
1306 digit_index = 0;
1307 digit_shift = 0;
1308 do {
1309 while (digit_shift <= BIGDIGIT_SIZE - shift && pos > (memSizeType) negative) {
1310 pos--;
1311 /* printf("A result->mem[" FMT_U_MEM "] = %c\n", pos,
1312 digits[(unsigned_digit >> digit_shift) & mask]); */
1313 result->mem[pos] = (strElemType) (digits[(unsigned_digit >> digit_shift) & mask]);
1314 digit_shift += shift;
1315 } /* while */
1316 digit_index++;
1317 if (digit_index < unsigned_size) {
1318 if (digit_shift == BIGDIGIT_SIZE) {
1319 unsigned_digit = unsigned_big->bigdigits[digit_index];
1320 digit_shift = 0;
1321 } else {
1322 unsigned_digit >>= digit_shift;
1323 unsigned_digit |=
1324 unsigned_big->bigdigits[digit_index] << (BIGDIGIT_SIZE - digit_shift);
1325 if (pos > (memSizeType) negative) {
1326 pos--;
1327 /* printf("B result->mem[" FMT_U_MEM "] = %c\n", pos,
1328 digits[unsigned_digit & mask]); */
1329 result->mem[pos] = (strElemType) (digits[unsigned_digit & mask]);
1330 unsigned_digit = unsigned_big->bigdigits[digit_index];
1331 digit_shift += shift - BIGDIGIT_SIZE;
1332 } /* if */
1333 } /* if */
1334 } else if (digit_shift != BIGDIGIT_SIZE && pos > (memSizeType) negative) {
1335 pos--;
1336 /* printf("C result->mem[" FMT_U_MEM "] = %c\n", pos,
1337 digits[(unsigned_digit >> digit_shift) & mask]); */
1338 result->mem[pos] = (strElemType) (digits[(unsigned_digit >> digit_shift) & mask]);
1339 } /* if */
1340 } while (digit_index < unsigned_size && pos > (memSizeType) negative);
1341 if (negative) {
1342 pos--;
1343 /* printf("result->mem[" FMT_U_MEM "] = -\n", pos); */
1344 result->mem[pos] = (strElemType) '-';
1345 } /* if */
1346 result->size = result_size;
1347 } /* if */
1348 } /* if */
1349 if (unsigned_big != big1) {
1350 FREE_BIG(unsigned_big, unsigned_big->size);
1351 } /* if */
1352 } /* if */
1353 logFunction(printf("bigRadixPow2 --> \"%s\"\n", striAsUnquotedCStri(result)););
1354 return result;
1355 } /* bigRadixPow2 */
1356
1357
1358
1359 /**
1360 * Convert a big integer number to a string using a radix.
1361 * The conversion uses the numeral system with the given base.
1362 * Digit values from 10 upward are encoded with letters.
1363 * For negative numbers a minus sign is prepended.
1364 * @param big1 BigInteger number to be converted.
1365 * @param base Base of numeral system (base >= 2 and base <= 36 holds).
1366 * @param upperCase Decides about the letter case.
1367 * @return the string result of the conversion.
1368 * @exception MEMORY_ERROR Not enough memory to represent the result.
1369 */
bigRadix2To36(const const_bigIntType big1,unsigned int base,boolType upperCase)1370 static striType bigRadix2To36 (const const_bigIntType big1, unsigned int base,
1371 boolType upperCase)
1372
1373 {
1374 unsigned int estimate_shift;
1375 bigIntType unsigned_big;
1376 boolType negative;
1377 memSizeType pos;
1378 memSizeType result_size;
1379 memSizeType final_result_size;
1380 striType resized_result;
1381 striType result;
1382
1383 /* bigRadix2To36 */
1384 logFunction(printf("bigRadix2To36(%s, %u, %d)\n",
1385 bigHexCStri(big1), base, upperCase););
1386 negative = IS_NEGATIVE(big1->bigdigits[big1->size - 1]);
1387 /* A power of two that is less or equal than the base is */
1388 /* used to estimate the size of the result. */
1389 estimate_shift = (unsigned int) uint8MostSignificantBit((uint8Type) base);
1390 if (unlikely((MAX_STRI_LEN <= (MAX_MEMSIZETYPE - 1) / estimate_shift +
1391 (unsigned int) negative + 1 &&
1392 big1->size > ((MAX_STRI_LEN - (unsigned int) negative - 1) *
1393 estimate_shift + 1) / BIGDIGIT_SIZE) ||
1394 big1->size > MAX_MEMSIZETYPE / BIGDIGIT_SIZE)) {
1395 raise_error(MEMORY_ERROR);
1396 result = NULL;
1397 } else {
1398 /* The size of the result is computed by computing the */
1399 /* number of radix digits plus one character for the sign. */
1400 result_size = (big1->size * BIGDIGIT_SIZE - 1) / estimate_shift + (unsigned int) negative + 1;
1401 /* printf("result_size: " FMT_U_MEM "\n", result_size); */
1402 if (unlikely(!ALLOC_STRI_SIZE_OK(result, result_size))) {
1403 raise_error(MEMORY_ERROR);
1404 result = NULL;
1405 } else {
1406 if (negative) {
1407 unsigned_big = alloc_positive_copy_of_negative_big(big1);
1408 } else if (likely(ALLOC_BIG_SIZE_OK(unsigned_big, big1->size))) {
1409 unsigned_big->size = big1->size;
1410 memcpy(unsigned_big->bigdigits, big1->bigdigits,
1411 (size_t) big1->size * sizeof(bigDigitType));
1412 } /* if */
1413 if (unlikely(unsigned_big == NULL)) {
1414 FREE_STRI(result, result_size);
1415 raise_error(MEMORY_ERROR);
1416 result = NULL;
1417 } else {
1418 /* pos = basicRadix2To36(unsigned_big, result, base,
1419 digitTable[upperCase], result_size - 1); */
1420 pos = binaryRadix2To36(unsigned_big, result, base,
1421 digitTable[upperCase], (unsigned int)
1422 memSizeMostSignificantBit(result_size) + 1,
1423 FALSE, result_size - 1);
1424 FREE_BIG(unsigned_big, big1->size);
1425 pos++;
1426 if (negative) {
1427 final_result_size = result_size - pos + 1;
1428 result->mem[0] = '-';
1429 memmove(&result->mem[1], &result->mem[pos],
1430 (result_size - pos) * sizeof(strElemType));
1431 } else {
1432 final_result_size = result_size - pos;
1433 memmove(&result->mem[0], &result->mem[pos],
1434 (result_size - pos) * sizeof(strElemType));
1435 } /* if */
1436 result->size = final_result_size;
1437 if (final_result_size < result_size) {
1438 REALLOC_STRI_SIZE_SMALLER(resized_result, result, result_size, final_result_size);
1439 if (unlikely(resized_result == NULL)) {
1440 FREE_STRI(result, result_size);
1441 raise_error(MEMORY_ERROR);
1442 result = NULL;
1443 } else {
1444 result = resized_result;
1445 COUNT3_STRI(result_size, final_result_size);
1446 } /* if */
1447 } /* if */
1448 } /* if */
1449 } /* if */
1450 } /* if */
1451 logFunction(printf("bigRadix2To36 --> \"%s\"\n", striAsUnquotedCStri(result)););
1452 return result;
1453 } /* bigRadix2To36 */
1454
1455
1456
1457 /**
1458 * Shifts the big integer big1 to the left by lshift bits.
1459 * Bits which are shifted out at the left of big1 are lost.
1460 * At the right of big1 zero bits are shifted in. The function
1461 * is called for 0 < lshift < BIGDIGIT_SIZE.
1462 */
uBigLShift(const bigIntType big1,const unsigned int lshift)1463 static void uBigLShift (const bigIntType big1, const unsigned int lshift)
1464
1465 {
1466 doubleBigDigitType carry = 0;
1467 memSizeType pos = 0;
1468
1469 /* uBigLShift */
1470 do {
1471 carry |= ((doubleBigDigitType) big1->bigdigits[pos]) << lshift;
1472 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
1473 carry >>= BIGDIGIT_SIZE;
1474 pos++;
1475 } while (pos < big1->size);
1476 } /* uBigLShift */
1477
1478
1479
1480 /**
1481 * Shifts the big integer big1 to the right by rshift bits.
1482 * Bits which are shifted out at the right of big1 are lost.
1483 * At the left of big1 zero bits are shifted in. The function
1484 * is called for 0 < rshift < BIGDIGIT_SIZE.
1485 */
uBigRShift(const bigIntType big1,const unsigned int rshift)1486 static void uBigRShift (const bigIntType big1, const unsigned int rshift)
1487
1488 {
1489 unsigned int lshift = BIGDIGIT_SIZE - rshift;
1490 bigDigitType low_digit;
1491 bigDigitType high_digit = 0;
1492 memSizeType pos;
1493
1494 /* uBigRShift */
1495 for (pos = big1->size - 1; pos != 0; pos--) {
1496 low_digit = big1->bigdigits[pos];
1497 big1->bigdigits[pos] = (bigDigitType)
1498 (((low_digit >> rshift) | (high_digit << lshift)) & BIGDIGIT_MASK);
1499 high_digit = low_digit;
1500 } /* for */
1501 low_digit = big1->bigdigits[0];
1502 big1->bigdigits[0] = (bigDigitType)
1503 (((low_digit >> rshift) | (high_digit << lshift)) & BIGDIGIT_MASK);
1504 } /* uBigRShift */
1505
1506
1507
1508 /**
1509 * Increments an unsigned big integer by 1.
1510 * This function does overflow silently if big1 contains
1511 * not enough digits.
1512 */
uBigIncr(const bigIntType big1)1513 static void uBigIncr (const bigIntType big1)
1514
1515 {
1516 memSizeType pos = 0;
1517
1518 /* uBigIncr */
1519 if (unlikely(big1->bigdigits[pos] == BIGDIGIT_MASK)) {
1520 if (big1->size == 1) {
1521 big1->bigdigits[pos] = 0;
1522 pos++;
1523 } else {
1524 do {
1525 big1->bigdigits[pos] = 0;
1526 pos++;
1527 } while (big1->bigdigits[pos] == BIGDIGIT_MASK);
1528 /* memset(big1->bigdigits, 0, pos * sizeof(bigDigitType)); */
1529 } /* if */
1530 } /* if */
1531 if (pos < big1->size) {
1532 big1->bigdigits[pos]++;
1533 } /* if */
1534 } /* uBigIncr */
1535
1536
1537
1538 /**
1539 * Decrements an unsigned big integer by 1.
1540 * This function does overflow silently if big1 contains
1541 * not enough digits. The function works correctly if there
1542 * are leading zereo digits.
1543 */
uBigDecr(const bigIntType big1)1544 static void uBigDecr (const bigIntType big1)
1545
1546 {
1547 memSizeType pos = 0;
1548
1549 /* uBigDecr */
1550 if (unlikely(big1->bigdigits[pos] == 0)) {
1551 do {
1552 big1->bigdigits[pos] = BIGDIGIT_MASK;
1553 pos++;
1554 } while (pos < big1->size && big1->bigdigits[pos] == 0);
1555 } /* if */
1556 if (pos < big1->size) {
1557 big1->bigdigits[pos]--;
1558 } /* if */
1559 } /* uBigDecr */
1560
1561
1562
1563 /**
1564 * Computes the quotient of an integer division of dividend by one
1565 * divisor_digit for nonnegative big integers. The divisor_digit
1566 * must not be zero.
1567 */
uBigDiv1(const const_bigIntType dividend,const bigDigitType divisor_digit,const bigIntType quotient)1568 static void uBigDiv1 (const const_bigIntType dividend,
1569 const bigDigitType divisor_digit, const bigIntType quotient)
1570
1571 {
1572 memSizeType pos;
1573 doubleBigDigitType carry = 0;
1574
1575 /* uBigDiv1 */
1576 pos = dividend->size;
1577 do {
1578 pos--;
1579 carry <<= BIGDIGIT_SIZE;
1580 carry += dividend->bigdigits[pos];
1581 quotient->bigdigits[pos] = (bigDigitType) ((carry / divisor_digit) & BIGDIGIT_MASK);
1582 carry %= divisor_digit;
1583 } while (pos > 0);
1584 } /* uBigDiv1 */
1585
1586
1587
1588 /**
1589 * Computes an integer division of dividend by one divisor_digit
1590 * for signed big integers. The memory for the quotient is requested
1591 * and the normalized quotient is returned. This function handles
1592 * also the special case of a division by zero.
1593 * @return the quotient of the integer division.
1594 * @exception NUMERIC_ERROR If a division by zero occurs.
1595 */
bigDiv1(const_bigIntType dividend,bigDigitType divisor_digit)1596 static bigIntType bigDiv1 (const_bigIntType dividend, bigDigitType divisor_digit)
1597
1598 {
1599 boolType negative = FALSE;
1600 bigIntType dividend_help = NULL;
1601 bigIntType quotient;
1602
1603 /* bigDiv1 */
1604 if (unlikely(divisor_digit == 0)) {
1605 logError(printf("bigDiv1(%s, " FMT_U_DIG "): Division by zero.\n",
1606 bigHexCStri(dividend), divisor_digit););
1607 raise_error(NUMERIC_ERROR);
1608 return NULL;
1609 } else {
1610 if (unlikely(!ALLOC_BIG_CHECK_SIZE(quotient, dividend->size + 1))) {
1611 raise_error(MEMORY_ERROR);
1612 return NULL;
1613 } else {
1614 quotient->size = dividend->size + 1;
1615 if (IS_NEGATIVE(dividend->bigdigits[dividend->size - 1])) {
1616 negative = TRUE;
1617 dividend_help = alloc_positive_copy_of_negative_big(dividend);
1618 dividend = dividend_help;
1619 if (unlikely(dividend_help == NULL)) {
1620 FREE_BIG(quotient, quotient->size);
1621 raise_error(MEMORY_ERROR);
1622 return NULL;
1623 } /* if */
1624 } /* if */
1625 quotient->bigdigits[quotient->size - 1] = 0;
1626 if (IS_NEGATIVE(divisor_digit)) {
1627 negative = !negative;
1628 /* The unsigned value is negated to avoid a signed integer */
1629 /* overflow if the smallest signed integer is negated. */
1630 divisor_digit = -divisor_digit;
1631 } /* if */
1632 uBigDiv1(dividend, divisor_digit, quotient);
1633 if (negative) {
1634 negate_positive_big(quotient);
1635 } /* if */
1636 quotient = normalize(quotient);
1637 if (dividend_help != NULL) {
1638 FREE_BIG(dividend_help, dividend_help->size);
1639 } /* if */
1640 return quotient;
1641 } /* if */
1642 } /* if */
1643 } /* bigDiv1 */
1644
1645
1646
1647 /**
1648 * Computes an integer division of dividend by divisor for signed big
1649 * integers if dividend has less digits than divisor. The memory for
1650 * the quotient is requested and the normalized quotient is returned. Normally
1651 * dividend->size < divisor->size implies abs(dividend) < abs(divisor).
1652 * If abs(dividend) < abs(divisor) holds the quotient is 0. The cases
1653 * dividend->size < divisor->size and abs(dividend) = abs(divisor) are if
1654 * dividend->size + 1 == divisor->size and dividend = 0x8000 (0x80000000...)
1655 * and divisor = 0x00008000 (0x000080000000...). In this cases the
1656 * quotient is -1. In all other cases the quotient is 0.
1657 * @return the quotient of the integer division.
1658 */
bigDivSizeLess(const const_bigIntType dividend,const const_bigIntType divisor)1659 static bigIntType bigDivSizeLess (const const_bigIntType dividend,
1660 const const_bigIntType divisor)
1661
1662 {
1663 memSizeType pos;
1664 bigIntType quotient;
1665
1666 /* bigDivSizeLess */
1667 if (unlikely(!ALLOC_BIG_SIZE_OK(quotient, 1))) {
1668 raise_error(MEMORY_ERROR);
1669 return NULL;
1670 } else {
1671 quotient->size = 1;
1672 if (unlikely(dividend->size + 1 == divisor->size &&
1673 dividend->bigdigits[dividend->size - 1] == BIGDIGIT_SIGN &&
1674 divisor->bigdigits[divisor->size - 1] == 0 &&
1675 divisor->bigdigits[divisor->size - 2] == BIGDIGIT_SIGN)) {
1676 quotient->bigdigits[0] = BIGDIGIT_MASK;
1677 pos = dividend->size - 1;
1678 while (pos > 0) {
1679 pos--;
1680 if (likely(dividend->bigdigits[pos] != 0 || divisor->bigdigits[pos] != 0)) {
1681 quotient->bigdigits[0] = 0;
1682 pos = 0;
1683 } /* if */
1684 } /* while */
1685 } else {
1686 quotient->bigdigits[0] = 0;
1687 } /* if */
1688 return quotient;
1689 } /* if */
1690 } /* bigDivSizeLess */
1691
1692
1693
1694 /**
1695 * Multiplies big2 with multiplier and subtracts the product from
1696 * big1 at the digit position pos1 of big1. Big1, big2 and
1697 * multiplier are nonnegative big integer values.
1698 * The algorithm tries to save computations. Therefore
1699 * there are checks for mult_carry != 0 and sbtr_carry == 0.
1700 */
uBigMultSub(const bigIntType big1,const const_bigIntType big2,const bigDigitType multiplier,const memSizeType pos1)1701 static bigDigitType uBigMultSub (const bigIntType big1, const const_bigIntType big2,
1702 const bigDigitType multiplier, const memSizeType pos1)
1703
1704 {
1705 memSizeType pos = 0;
1706 doubleBigDigitType mult_carry = 0;
1707 doubleBigDigitType sbtr_carry = 1;
1708
1709 /* uBigMultSub */
1710 do {
1711 mult_carry += (doubleBigDigitType) big2->bigdigits[pos] * multiplier;
1712 sbtr_carry += big1->bigdigits[pos1 + pos] + (~mult_carry & BIGDIGIT_MASK);
1713 big1->bigdigits[pos1 + pos] = (bigDigitType) (sbtr_carry & BIGDIGIT_MASK);
1714 mult_carry >>= BIGDIGIT_SIZE;
1715 sbtr_carry >>= BIGDIGIT_SIZE;
1716 pos++;
1717 } while (pos < big2->size);
1718 for (pos += pos1; mult_carry != 0 && pos < big1->size; pos++) {
1719 sbtr_carry += big1->bigdigits[pos] + (~mult_carry & BIGDIGIT_MASK);
1720 big1->bigdigits[pos] = (bigDigitType) (sbtr_carry & BIGDIGIT_MASK);
1721 mult_carry >>= BIGDIGIT_SIZE;
1722 sbtr_carry >>= BIGDIGIT_SIZE;
1723 } /* for */
1724 for (; sbtr_carry == 0 && pos < big1->size; pos++) {
1725 sbtr_carry = (doubleBigDigitType) big1->bigdigits[pos] + BIGDIGIT_MASK;
1726 big1->bigdigits[pos] = (bigDigitType) (sbtr_carry & BIGDIGIT_MASK);
1727 sbtr_carry >>= BIGDIGIT_SIZE;
1728 } /* for */
1729 return (bigDigitType) (sbtr_carry & BIGDIGIT_MASK);
1730 } /* uBigMultSub */
1731
1732
1733
1734 /**
1735 * Adds big2 to big1 at the digit position pos1. Big1 and big2
1736 * are nonnegative big integer values. The size of big1 must be
1737 * greater or equal the size of big2. The final carry is ignored.
1738 */
uBigAddTo(const bigIntType big1,const const_bigIntType big2,const memSizeType pos1)1739 static void uBigAddTo (const bigIntType big1, const const_bigIntType big2,
1740 const memSizeType pos1)
1741
1742 {
1743 memSizeType pos = 0;
1744 doubleBigDigitType carry = 0;
1745
1746 /* uBigAddTo */
1747 do {
1748 carry += (doubleBigDigitType) big1->bigdigits[pos1 + pos] + big2->bigdigits[pos];
1749 big1->bigdigits[pos1 + pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
1750 carry >>= BIGDIGIT_SIZE;
1751 pos++;
1752 } while (pos < big2->size);
1753 for (pos += pos1; pos < big1->size; pos++) {
1754 carry += big1->bigdigits[pos];
1755 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
1756 carry >>= BIGDIGIT_SIZE;
1757 } /* for */
1758 } /* uBigAddTo */
1759
1760
1761
1762 /**
1763 * Computes quotient and remainder of an integer division of dividend by
1764 * divisor for nonnegative big integers. The remainder is delivered in
1765 * dividend. There are several preconditions for this function. Divisor
1766 * must have at least 2 digits and dividend must have at least one
1767 * digit more than divisor. If dividend and divisor have the same length in
1768 * digits nothing is done. The most significant bit of divisor must be
1769 * set. The most significant digit of dividend must be less than the
1770 * most significant digit of divisor. The computations to meet this
1771 * predonditions are done outside this function. The special cases
1772 * with a one digit divisor or a dividend with less digits than divisor are
1773 * handled in other functions. This algorithm based on the algorithm
1774 * from D.E. Knuth described in "The art of computer programming"
1775 * volume 2 (Seminumerical algorithms).
1776 */
uBigDiv(const bigIntType dividend,const const_bigIntType divisor,const bigIntType quotient)1777 static void uBigDiv (const bigIntType dividend, const const_bigIntType divisor,
1778 const bigIntType quotient)
1779
1780 {
1781 memSizeType pos1;
1782 doubleBigDigitType twodigits;
1783 doubleBigDigitType remainder;
1784 bigDigitType quotientdigit;
1785 bigDigitType sbtr_carry;
1786
1787 /* uBigDiv */
1788 for (pos1 = dividend->size - 1; pos1 >= divisor->size; pos1--) {
1789 twodigits = (((doubleBigDigitType) dividend->bigdigits[pos1]) << BIGDIGIT_SIZE) |
1790 dividend->bigdigits[pos1 - 1];
1791 if (unlikely(dividend->bigdigits[pos1] == divisor->bigdigits[divisor->size - 1])) {
1792 quotientdigit = BIGDIGIT_MASK;
1793 } else {
1794 quotientdigit = (bigDigitType) (twodigits / divisor->bigdigits[divisor->size - 1]);
1795 } /* if */
1796 remainder = twodigits - (doubleBigDigitType) quotientdigit *
1797 divisor->bigdigits[divisor->size - 1];
1798 while (remainder <= BIGDIGIT_MASK &&
1799 (doubleBigDigitType) divisor->bigdigits[divisor->size - 2] * quotientdigit >
1800 (remainder << BIGDIGIT_SIZE | dividend->bigdigits[pos1 - 2])) {
1801 quotientdigit--;
1802 remainder = twodigits - (doubleBigDigitType) quotientdigit *
1803 divisor->bigdigits[divisor->size - 1];
1804 } /* while */
1805 sbtr_carry = uBigMultSub(dividend, divisor, quotientdigit, pos1 - divisor->size);
1806 if (sbtr_carry == 0) {
1807 uBigAddTo(dividend, divisor, pos1 - divisor->size);
1808 quotientdigit--;
1809 } /* if */
1810 quotient->bigdigits[pos1 - divisor->size] = quotientdigit;
1811 } /* for */
1812 } /* uBigDiv */
1813
1814
1815
1816 /**
1817 * Computes quotient and remainder of an integer division of dividend
1818 * by one divisor_digit for nonnegative big integers. The divisor_digit
1819 * must not be zero. The remainder of the division is returned.
1820 */
uBigDivRem1(const const_bigIntType dividend,const bigDigitType divisor_digit,const bigIntType quotient)1821 static bigDigitType uBigDivRem1 (const const_bigIntType dividend,
1822 const bigDigitType divisor_digit, const bigIntType quotient)
1823
1824 {
1825 memSizeType pos;
1826 doubleBigDigitType carry = 0;
1827
1828 /* uBigDivRem1 */
1829 pos = dividend->size;
1830 do {
1831 pos--;
1832 carry <<= BIGDIGIT_SIZE;
1833 carry += dividend->bigdigits[pos];
1834 quotient->bigdigits[pos] = (bigDigitType) ((carry / divisor_digit) & BIGDIGIT_MASK);
1835 carry %= divisor_digit;
1836 } while (pos > 0);
1837 return (bigDigitType) carry;
1838 } /* uBigDivRem1 */
1839
1840
1841 /**
1842 * Computes quotient and remainder of the integer division dividend
1843 * by one divisor_digit for signed big integers. The memory for the
1844 * quotient is requested and the normalized quotient is returned.
1845 * The memory for the remainder is requested and the normalized
1846 * remainder is assigned to *remainder. This function handles also
1847 * the special case of a division by zero.
1848 * @return the quotient of the integer division.
1849 * @exception NUMERIC_ERROR If a division by zero occurs.
1850 */
bigDivRem1(const_bigIntType dividend,bigDigitType divisor_digit,bigIntType * remainder)1851 static bigIntType bigDivRem1 (const_bigIntType dividend, bigDigitType divisor_digit,
1852 bigIntType *remainder)
1853
1854 {
1855 boolType quotientNegative = FALSE;
1856 boolType remainderNegative = FALSE;
1857 bigIntType dividend_help = NULL;
1858 bigIntType quotient;
1859
1860 /* bigDivRem1 */
1861 if (unlikely(divisor_digit == 0)) {
1862 logError(printf("bigDivRem1(%s, " FMT_U_DIG "): Division by zero.\n",
1863 bigHexCStri(dividend), divisor_digit););
1864 *remainder = NULL;
1865 raise_error(NUMERIC_ERROR);
1866 return NULL;
1867 } else {
1868 if (unlikely(!ALLOC_BIG_CHECK_SIZE(quotient, dividend->size + 1))) {
1869 *remainder = NULL;
1870 raise_error(MEMORY_ERROR);
1871 return NULL;
1872 } else if (unlikely(!ALLOC_BIG_SIZE_OK(*remainder, 1))) {
1873 FREE_BIG(quotient, quotient->size);
1874 raise_error(MEMORY_ERROR);
1875 return NULL;
1876 } else {
1877 quotient->size = dividend->size + 1;
1878 (*remainder)->size = 1;
1879 if (IS_NEGATIVE(dividend->bigdigits[dividend->size - 1])) {
1880 quotientNegative = TRUE;
1881 remainderNegative = TRUE;
1882 dividend_help = alloc_positive_copy_of_negative_big(dividend);
1883 dividend = dividend_help;
1884 if (unlikely(dividend_help == NULL)) {
1885 FREE_BIG(quotient, quotient->size);
1886 FREE_BIG(*remainder, (*remainder)->size);
1887 *remainder = NULL;
1888 raise_error(MEMORY_ERROR);
1889 return NULL;
1890 } /* if */
1891 } /* if */
1892 quotient->bigdigits[quotient->size - 1] = 0;
1893 if (IS_NEGATIVE(divisor_digit)) {
1894 quotientNegative = !quotientNegative;
1895 /* The unsigned value is negated to avoid a signed integer */
1896 /* overflow if the smallest signed integer is negated. */
1897 divisor_digit = -divisor_digit;
1898 } /* if */
1899 (*remainder)->bigdigits[0] = uBigDivRem1(dividend, divisor_digit, quotient);
1900 if (quotientNegative) {
1901 negate_positive_big(quotient);
1902 } /* if */
1903 quotient = normalize(quotient);
1904 if (remainderNegative) {
1905 negate_positive_big(*remainder);
1906 } /* if */
1907 if (dividend_help != NULL) {
1908 FREE_BIG(dividend_help, dividend_help->size);
1909 } /* if */
1910 return quotient;
1911 } /* if */
1912 } /* if */
1913 } /* bigDivRem1 */
1914
1915
1916
1917 /**
1918 * Computes quotient and remainder of the integer division of dividend
1919 * by divisor for signed big integers if dividend has less digits than
1920 * divisor. The memory for the quotient is requested and the normalized
1921 * quotient is returned. The memory for the remainder is requested and
1922 * the normalized remainder is assigned to *remainder. Normally
1923 * dividend->size < divisor->size implies abs(dividend) < abs(divisor).
1924 * If abs(dividend) < abs(divisor) holds the quotient is 0 and the
1925 * remainder is dividend. The cases
1926 * dividend->size < divisor->size and abs(dividend) = abs(divisor) are if
1927 * dividend->size + 1 == divisor->size and dividend = 0x8000 (0x80000000...)
1928 * and divisor = 0x00008000 (0x000080000000...). In this cases the
1929 * quotient is -1 and the remainder is 0. In all other cases the quotient
1930 * is 0 and the remainder is dividend.
1931 * @return the quotient of the integer division.
1932 */
bigDivRemSizeLess(const const_bigIntType dividend,const const_bigIntType divisor,bigIntType * remainder)1933 static bigIntType bigDivRemSizeLess (const const_bigIntType dividend,
1934 const const_bigIntType divisor, bigIntType *remainder)
1935
1936 {
1937 memSizeType pos;
1938 boolType remainderIs0;
1939 bigIntType quotient;
1940
1941 /* bigDivRemSizeLess */
1942 if (unlikely(!ALLOC_BIG_SIZE_OK(quotient, 1))) {
1943 *remainder = NULL;
1944 raise_error(MEMORY_ERROR);
1945 } else {
1946 quotient->size = 1;
1947 if (unlikely(dividend->size + 1 == divisor->size &&
1948 dividend->bigdigits[dividend->size - 1] == BIGDIGIT_SIGN &&
1949 divisor->bigdigits[divisor->size - 1] == 0 &&
1950 divisor->bigdigits[divisor->size - 2] == BIGDIGIT_SIGN)) {
1951 remainderIs0 = TRUE;
1952 pos = dividend->size - 1;
1953 while (pos > 0) {
1954 pos--;
1955 if (likely(dividend->bigdigits[pos] != 0 || divisor->bigdigits[pos] != 0)) {
1956 remainderIs0 = FALSE;
1957 pos = 0;
1958 } /* if */
1959 } /* while */
1960 } else {
1961 remainderIs0 = FALSE;
1962 } /* if */
1963 if (remainderIs0) {
1964 if (unlikely(!ALLOC_BIG_SIZE_OK(*remainder, 1))) {
1965 FREE_BIG(quotient, 1);
1966 raise_error(MEMORY_ERROR);
1967 quotient = NULL;
1968 } else {
1969 (*remainder)->size = 1;
1970 (*remainder)->bigdigits[0] = 0;
1971 quotient->bigdigits[0] = BIGDIGIT_MASK;
1972 } /* if */
1973 } else {
1974 if (unlikely(!ALLOC_BIG_SIZE_OK(*remainder, dividend->size))) {
1975 FREE_BIG(quotient, 1);
1976 raise_error(MEMORY_ERROR);
1977 quotient = NULL;
1978 } else {
1979 (*remainder)->size = dividend->size;
1980 memcpy((*remainder)->bigdigits, dividend->bigdigits,
1981 (size_t) dividend->size * sizeof(bigDigitType));
1982 quotient->bigdigits[0] = 0;
1983 } /* if */
1984 } /* if */
1985 } /* if */
1986 return quotient;
1987 } /* bigDivRemSizeLess */
1988
1989
1990
1991 /**
1992 * Computes the remainder of an integer division of dividend by
1993 * one divisor_digit for nonnegative big integers. The divisor_digit must
1994 * not be zero.
1995 */
uBigRem1(const const_bigIntType dividend,const bigDigitType divisor_digit)1996 static bigDigitType uBigRem1 (const const_bigIntType dividend,
1997 const bigDigitType divisor_digit)
1998
1999 {
2000 memSizeType pos;
2001 doubleBigDigitType carry = 0;
2002
2003 /* uBigRem1 */
2004 pos = dividend->size;
2005 do {
2006 pos--;
2007 carry <<= BIGDIGIT_SIZE;
2008 carry += dividend->bigdigits[pos];
2009 carry %= divisor_digit;
2010 } while (pos > 0);
2011 return (bigDigitType) carry;
2012 } /* uBigRem1 */
2013
2014
2015
2016 /**
2017 * Computes the remainder of the integer division dividend by one
2018 * divisor_digit for signed big integers. The memory for the
2019 * remainder is requested and the normalized remainder is
2020 * returned. This function handles also the special case of a
2021 * division by zero.
2022 * @return the remainder of the integer division.
2023 * @exception NUMERIC_ERROR If a division by zero occurs.
2024 */
bigRem1(const_bigIntType dividend,bigDigitType divisor_digit)2025 static bigIntType bigRem1 (const_bigIntType dividend, bigDigitType divisor_digit)
2026
2027 {
2028 boolType negative = FALSE;
2029 bigIntType dividend_help = NULL;
2030 bigIntType remainder;
2031
2032 /* bigRem1 */
2033 if (unlikely(divisor_digit == 0)) {
2034 logError(printf("bigRem1(%s, " FMT_U_DIG "): Division by zero.\n",
2035 bigHexCStri(dividend), divisor_digit););
2036 raise_error(NUMERIC_ERROR);
2037 return NULL;
2038 } else {
2039 if (unlikely(!ALLOC_BIG_SIZE_OK(remainder, 1))) {
2040 raise_error(MEMORY_ERROR);
2041 return NULL;
2042 } else {
2043 remainder->size = 1;
2044 if (IS_NEGATIVE(dividend->bigdigits[dividend->size - 1])) {
2045 negative = TRUE;
2046 dividend_help = alloc_positive_copy_of_negative_big(dividend);
2047 dividend = dividend_help;
2048 if (unlikely(dividend_help == NULL)) {
2049 FREE_BIG(remainder, remainder->size);
2050 raise_error(MEMORY_ERROR);
2051 return NULL;
2052 } /* if */
2053 } /* if */
2054 if (IS_NEGATIVE(divisor_digit)) {
2055 /* The unsigned value is negated to avoid a signed integer */
2056 /* overflow if the smallest signed integer is negated. */
2057 divisor_digit = -divisor_digit;
2058 } /* if */
2059 remainder->bigdigits[0] = uBigRem1(dividend, divisor_digit);
2060 if (negative) {
2061 negate_positive_big(remainder);
2062 } /* if */
2063 if (dividend_help != NULL) {
2064 FREE_BIG(dividend_help, dividend_help->size);
2065 } /* if */
2066 return remainder;
2067 } /* if */
2068 } /* if */
2069 } /* bigRem1 */
2070
2071
2072
2073 /**
2074 * Computes an integer modulo division of dividend by one
2075 * divisor_digit for signed big integers. The memory for the
2076 * quotient is requested and the normalized quotient is returned.
2077 * This function handles also the special case of a division by
2078 * zero.
2079 * @return the quotient of the integer division.
2080 * @exception NUMERIC_ERROR If a division by zero occurs.
2081 */
bigMDiv1(const_bigIntType dividend,bigDigitType divisor_digit)2082 static bigIntType bigMDiv1 (const_bigIntType dividend, bigDigitType divisor_digit)
2083
2084 {
2085 boolType negative = FALSE;
2086 bigIntType dividend_help = NULL;
2087 bigDigitType remainder;
2088 bigIntType quotient;
2089
2090 /* bigMDiv1 */
2091 if (unlikely(divisor_digit == 0)) {
2092 logError(printf("bigMDiv1(%s, " FMT_U_DIG "): Division by zero.\n",
2093 bigHexCStri(dividend), divisor_digit););
2094 raise_error(NUMERIC_ERROR);
2095 return NULL;
2096 } else {
2097 if (unlikely(!ALLOC_BIG_CHECK_SIZE(quotient, dividend->size + 1))) {
2098 raise_error(MEMORY_ERROR);
2099 return NULL;
2100 } else {
2101 quotient->size = dividend->size + 1;
2102 if (IS_NEGATIVE(dividend->bigdigits[dividend->size - 1])) {
2103 negative = TRUE;
2104 dividend_help = alloc_positive_copy_of_negative_big(dividend);
2105 dividend = dividend_help;
2106 if (unlikely(dividend_help == NULL)) {
2107 FREE_BIG(quotient, quotient->size);
2108 raise_error(MEMORY_ERROR);
2109 return NULL;
2110 } /* if */
2111 } /* if */
2112 quotient->bigdigits[quotient->size - 1] = 0;
2113 if (IS_NEGATIVE(divisor_digit)) {
2114 negative = !negative;
2115 /* The unsigned value is negated to avoid a signed integer */
2116 /* overflow if the smallest signed integer is negated. */
2117 divisor_digit = -divisor_digit;
2118 } /* if */
2119 remainder = uBigDivRem1(dividend, divisor_digit, quotient);
2120 if (negative) {
2121 if (remainder != 0) {
2122 uBigIncr(quotient);
2123 } /* if */
2124 negate_positive_big(quotient);
2125 } /* if */
2126 quotient = normalize(quotient);
2127 if (dividend_help != NULL) {
2128 FREE_BIG(dividend_help, dividend_help->size);
2129 } /* if */
2130 return quotient;
2131 } /* if */
2132 } /* if */
2133 } /* bigMDiv1 */
2134
2135
2136
2137 /**
2138 * Computes a modulo integer division of dividend by divisor for signed
2139 * big integers if dividend has less digits than divisor. The memory for
2140 * the quotient is requested and the normalized quotient is returned.
2141 * If the dividend is zero the quotient is always zero. Otherwise if
2142 * the signs of dividend and divisor differ the quotient is -1.
2143 * In all other cases the quotient is zero.
2144 * @return the quotient of the integer division.
2145 */
bigMDivSizeLess(const const_bigIntType dividend,const const_bigIntType divisor)2146 static bigIntType bigMDivSizeLess (const const_bigIntType dividend,
2147 const const_bigIntType divisor)
2148
2149 {
2150 bigIntType quotient;
2151
2152 /* bigMDivSizeLess */
2153 logFunction(printf("bigMDivSizeLess(%s,", bigHexCStri(dividend));
2154 printf("%s)\n", bigHexCStri(divisor)););
2155 if (unlikely(!ALLOC_BIG_SIZE_OK(quotient, 1))) {
2156 raise_error(MEMORY_ERROR);
2157 } else {
2158 quotient->size = 1;
2159 if ((dividend->size == 1 && dividend->bigdigits[0] == 0) ||
2160 IS_NEGATIVE(dividend->bigdigits[dividend->size - 1]) ==
2161 IS_NEGATIVE(divisor->bigdigits[divisor->size - 1])) {
2162 quotient->bigdigits[0] = 0;
2163 } else {
2164 quotient->bigdigits[0] = BIGDIGIT_MASK;
2165 } /* if */
2166 } /* if */
2167 logFunction(printf("bigMDivSizeLess --> %s\n", bigHexCStri(quotient)););
2168 return quotient;
2169 } /* bigMDivSizeLess */
2170
2171
2172
2173 /**
2174 * Computes the modulo of the integer division dividend by one
2175 * digit for signed big integers. The memory for the modulo is
2176 * requested and the normalized modulo is returned. This function
2177 * handles also the special case of a division by zero.
2178 */
bigMod1(const const_bigIntType dividend,const bigDigitType divisor_digit)2179 static bigIntType bigMod1 (const const_bigIntType dividend, const bigDigitType divisor_digit)
2180
2181 {
2182 bigIntType modulo;
2183
2184 /* bigMod1 */
2185 modulo = bigRem1(dividend, divisor_digit);
2186 if (IS_NEGATIVE(dividend->bigdigits[dividend->size - 1]) != IS_NEGATIVE(divisor_digit) &&
2187 modulo != NULL && modulo->bigdigits[0] != 0) {
2188 modulo->bigdigits[0] += divisor_digit;
2189 } /* if */
2190 return modulo;
2191 } /* bigMod1 */
2192
2193
2194
2195 /**
2196 * Computes the remainder of the integer division dividend by divisor for
2197 * signed big integers if dividend has less digits than divisor. The memory
2198 * for the remainder is requested and the normalized remainder is returned.
2199 * Normally dividend->size < divisor->size implies abs(dividend) < abs(divisor).
2200 * If abs(dividend) < abs(divisor) holds the remainder is dividend. The cases
2201 * dividend->size < divisor->size and abs(dividend) = abs(divisor) are if
2202 * dividend->size + 1 == divisor->size and dividend = 0x8000 (0x80000000...)
2203 * and divisor = 0x00008000 (0x000080000000...). In this cases the
2204 * remainder is 0. In all other cases the remainder is dividend.
2205 */
bigRemSizeLess(const const_bigIntType dividend,const const_bigIntType divisor)2206 static bigIntType bigRemSizeLess (const const_bigIntType dividend,
2207 const const_bigIntType divisor)
2208
2209 {
2210 memSizeType pos;
2211 boolType remainderIs0;
2212 bigIntType remainder;
2213
2214 /* bigRemSizeLess */
2215 if (dividend->size + 1 == divisor->size &&
2216 dividend->bigdigits[dividend->size - 1] == BIGDIGIT_SIGN &&
2217 divisor->bigdigits[divisor->size - 1] == 0 &&
2218 divisor->bigdigits[divisor->size - 2] == BIGDIGIT_SIGN) {
2219 remainderIs0 = TRUE;
2220 for (pos = 0; pos < dividend->size - 1; pos++) {
2221 if (dividend->bigdigits[pos] != 0 || divisor->bigdigits[pos] != 0) {
2222 remainderIs0 = FALSE;
2223 } /* if */
2224 } /* for */
2225 } else {
2226 remainderIs0 = FALSE;
2227 } /* if */
2228 if (remainderIs0) {
2229 if (unlikely(!ALLOC_BIG_SIZE_OK(remainder, 1))) {
2230 raise_error(MEMORY_ERROR);
2231 } else {
2232 remainder->size = 1;
2233 remainder->bigdigits[0] = 0;
2234 } /* if */
2235 } else {
2236 if (unlikely(!ALLOC_BIG_SIZE_OK(remainder, dividend->size))) {
2237 raise_error(MEMORY_ERROR);
2238 } else {
2239 remainder->size = dividend->size;
2240 memcpy(remainder->bigdigits, dividend->bigdigits,
2241 (size_t) dividend->size * sizeof(bigDigitType));
2242 } /* if */
2243 } /* if */
2244 return remainder;
2245 } /* bigRemSizeLess */
2246
2247
2248
2249 /**
2250 * Adds big2 to big1 at the digit position pos1. Big1 and big2
2251 * are signed big integer values. The size of big1 must be
2252 * greater or equal the size of big2.
2253 */
bigAddTo(const bigIntType big1,const const_bigIntType big2)2254 static void bigAddTo (const bigIntType big1, const const_bigIntType big2)
2255
2256 {
2257 memSizeType pos = 0;
2258 doubleBigDigitType carry = 0;
2259 doubleBigDigitType big2_sign;
2260
2261 /* bigAddTo */
2262 do {
2263 carry += (doubleBigDigitType) big1->bigdigits[pos] + big2->bigdigits[pos];
2264 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
2265 carry >>= BIGDIGIT_SIZE;
2266 pos++;
2267 } while (pos < big2->size);
2268 big2_sign = IS_NEGATIVE(big2->bigdigits[pos - 1]) ? BIGDIGIT_MASK : 0;
2269 for (; pos < big1->size; pos++) {
2270 carry += big1->bigdigits[pos] + big2_sign;
2271 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
2272 carry >>= BIGDIGIT_SIZE;
2273 } /* for */
2274 } /* bigAddTo */
2275
2276
2277
2278 /**
2279 * Computes the modulo of the integer division dividend by divisor for
2280 * signed big integers if dividend has less digits than divisor. The memory
2281 * for the modulo is requested and the normalized modulo is returned.
2282 * There are two cases: If the modulo division (see bigMDivSizeLess() )
2283 * would compute a quotient of zero the modulo is equal to the dividend.
2284 * In all other cases the quotient would be -1 and the modulo is computed
2285 * as divisor + dividend.
2286 * @return the modulo of the integer division.
2287 */
bigModSizeLess(const const_bigIntType dividend,const const_bigIntType divisor)2288 static bigIntType bigModSizeLess (const const_bigIntType dividend,
2289 const const_bigIntType divisor)
2290
2291 {
2292 bigIntType modulo;
2293
2294 /* bigModSizeLess */
2295 logFunction(printf("bigModSizeLess(%s,", bigHexCStri(dividend));
2296 printf("%s)\n", bigHexCStri(divisor)););
2297 if ((dividend->size == 1 && dividend->bigdigits[0] == 0) ||
2298 IS_NEGATIVE(dividend->bigdigits[dividend->size - 1]) ==
2299 IS_NEGATIVE(divisor->bigdigits[divisor->size - 1])) {
2300 /* The quotient is zero. */
2301 if (unlikely(!ALLOC_BIG_SIZE_OK(modulo, dividend->size))) {
2302 raise_error(MEMORY_ERROR);
2303 } else {
2304 modulo->size = dividend->size;
2305 memcpy(modulo->bigdigits, dividend->bigdigits,
2306 (size_t) dividend->size * sizeof(bigDigitType));
2307 } /* if */
2308 } else {
2309 /* The quotient is -1. */
2310 if (unlikely(!ALLOC_BIG_SIZE_OK(modulo, divisor->size))) {
2311 raise_error(MEMORY_ERROR);
2312 } else {
2313 modulo->size = divisor->size;
2314 memcpy(modulo->bigdigits, divisor->bigdigits,
2315 (size_t) divisor->size * sizeof(bigDigitType));
2316 bigAddTo(modulo, dividend);
2317 modulo = normalize(modulo);
2318 } /* if */
2319 } /* if */
2320 logFunction(printf("bigModSizeLess --> %s\n", bigHexCStri(quotient)););
2321 return modulo;
2322 } /* bigModSizeLess */
2323
2324
2325
2326 /**
2327 * Computes the remainder of an integer division of dividend by divisor
2328 * for nonnegative big integers. The remainder is delivered in
2329 * dividend. There are several preconditions for this function. Divisor
2330 * must have at least 2 digits and dividend must have at least one
2331 * digit more than divisor. If dividend and divisor have the same length in
2332 * digits nothing is done. The most significant bit of divisor must be
2333 * set. The most significant digit of dividend must be less than the
2334 * most significant digit of divisor. The computations to meet this
2335 * predonditions are done outside this function. The special cases
2336 * with a one digit divisor or a dividend with less digits than divisor are
2337 * handled in other functions. This algorithm based on the algorithm
2338 * from D.E. Knuth described in "The art of computer programming"
2339 * volume 2 (Seminumerical algorithms).
2340 */
uBigRem(const bigIntType dividend,const const_bigIntType divisor)2341 static void uBigRem (const bigIntType dividend, const const_bigIntType divisor)
2342
2343 {
2344 memSizeType pos1;
2345 doubleBigDigitType twodigits;
2346 doubleBigDigitType remainder;
2347 bigDigitType quotientdigit;
2348 bigDigitType sbtr_carry;
2349
2350 /* uBigRem */
2351 for (pos1 = dividend->size - 1; pos1 >= divisor->size; pos1--) {
2352 twodigits = (((doubleBigDigitType) dividend->bigdigits[pos1]) << BIGDIGIT_SIZE) |
2353 dividend->bigdigits[pos1 - 1];
2354 if (unlikely(dividend->bigdigits[pos1] == divisor->bigdigits[divisor->size - 1])) {
2355 quotientdigit = BIGDIGIT_MASK;
2356 } else {
2357 quotientdigit = (bigDigitType) (twodigits / divisor->bigdigits[divisor->size - 1]);
2358 } /* if */
2359 remainder = twodigits - (doubleBigDigitType) quotientdigit *
2360 divisor->bigdigits[divisor->size - 1];
2361 while (remainder <= BIGDIGIT_MASK &&
2362 (doubleBigDigitType) divisor->bigdigits[divisor->size - 2] * quotientdigit >
2363 (remainder << BIGDIGIT_SIZE | dividend->bigdigits[pos1 - 2])) {
2364 quotientdigit--;
2365 remainder = twodigits - (doubleBigDigitType) quotientdigit *
2366 divisor->bigdigits[divisor->size - 1];
2367 } /* while */
2368 sbtr_carry = uBigMultSub(dividend, divisor, quotientdigit, pos1 - divisor->size);
2369 if (sbtr_carry == 0) {
2370 uBigAddTo(dividend, divisor, pos1 - divisor->size);
2371 } /* if */
2372 } /* for */
2373 } /* uBigRem */
2374
2375
2376
uBigDigitAdd(const bigDigitType * const big1,const memSizeType size1,const bigDigitType * const big2,const memSizeType size2,bigDigitType * const result)2377 static void uBigDigitAdd (const bigDigitType *const big1, const memSizeType size1,
2378 const bigDigitType *const big2, const memSizeType size2, bigDigitType *const result)
2379
2380 {
2381 memSizeType pos = 0;
2382 doubleBigDigitType carry = 0;
2383
2384 /* uBigDigitAdd */
2385 do {
2386 carry += (doubleBigDigitType) big1[pos] + big2[pos];
2387 result[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
2388 carry >>= BIGDIGIT_SIZE;
2389 pos++;
2390 } while (pos < size2);
2391 for (; pos < size1; pos++) {
2392 carry += big1[pos];
2393 result[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
2394 carry >>= BIGDIGIT_SIZE;
2395 } /* for */
2396 result[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
2397 } /* uBigDigitAdd */
2398
2399
2400
uBigDigitSbtrFrom(bigDigitType * const big1,const memSizeType size1,const bigDigitType * const big2,const memSizeType size2)2401 static void uBigDigitSbtrFrom (bigDigitType *const big1, const memSizeType size1,
2402 const bigDigitType *const big2, const memSizeType size2)
2403
2404 {
2405 memSizeType pos = 0;
2406 doubleBigDigitType carry = 1;
2407
2408 /* uBigDigitSbtrFrom */
2409 do {
2410 carry += (doubleBigDigitType) big1[pos] +
2411 (~big2[pos] & BIGDIGIT_MASK);
2412 big1[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
2413 carry >>= BIGDIGIT_SIZE;
2414 pos++;
2415 } while (pos < size2);
2416 for (; carry == 0 && pos < size1; pos++) {
2417 carry = (doubleBigDigitType) big1[pos] + BIGDIGIT_MASK;
2418 big1[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
2419 carry >>= BIGDIGIT_SIZE;
2420 } /* for */
2421 } /* uBigDigitSbtrFrom */
2422
2423
2424
uBigDigitAddTo(bigDigitType * const big1,const memSizeType size1,const bigDigitType * const big2,const memSizeType size2)2425 static void uBigDigitAddTo (bigDigitType *const big1, const memSizeType size1,
2426 const bigDigitType *const big2, const memSizeType size2)
2427
2428 {
2429 memSizeType pos = 0;
2430 doubleBigDigitType carry = 0;
2431
2432 /* uBigDigitAddTo */
2433 do {
2434 carry += (doubleBigDigitType) big1[pos] + big2[pos];
2435 big1[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
2436 carry >>= BIGDIGIT_SIZE;
2437 pos++;
2438 } while (pos < size2);
2439 for (; carry != 0 && pos < size1; pos++) {
2440 carry += big1[pos];
2441 big1[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
2442 carry >>= BIGDIGIT_SIZE;
2443 } /* for */
2444 } /* uBigDigitAddTo */
2445
2446
2447
2448 #ifdef OUT_OF_ORDER
uBigDigitMult(const bigDigitType * const factor1,const bigDigitType * const factor2,const memSizeType size,bigDigitType * const product)2449 static void uBigDigitMult (const bigDigitType *const factor1,
2450 const bigDigitType *const factor2, const memSizeType size,
2451 bigDigitType *const product)
2452
2453 {
2454 memSizeType pos1;
2455 memSizeType pos2;
2456 doubleBigDigitType carry;
2457 doubleBigDigitType carry2 = 0;
2458 doubleBigDigitType prod;
2459
2460 /* uBigDigitMult */
2461 carry = (doubleBigDigitType) factor1[0] * factor2[0];
2462 product[0] = (bigDigitType) (carry & BIGDIGIT_MASK);
2463 carry >>= BIGDIGIT_SIZE;
2464 for (pos1 = 1; pos1 < size; pos1++) {
2465 pos2 = 0;
2466 do {
2467 prod = (doubleBigDigitType) factor1[pos2] * factor2[pos1 - pos2];
2468 if (unlikely(carry > (doubleBigDigitType) ~prod)) {
2469 carry2++;
2470 } /* if */
2471 carry += prod;
2472 pos2++;
2473 } while (pos2 <= pos1);
2474 product[pos1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2475 carry >>= BIGDIGIT_SIZE;
2476 carry |= (carry2 & BIGDIGIT_MASK) << BIGDIGIT_SIZE;
2477 carry2 >>= BIGDIGIT_SIZE;
2478 } /* for */
2479 for (; pos1 < size + size - 1; pos1++) {
2480 pos2 = pos1 - size + 1;
2481 do {
2482 prod = (doubleBigDigitType) factor1[pos2] * factor2[pos1 - pos2];
2483 if (unlikely(carry > (doubleBigDigitType) ~prod)) {
2484 carry2++;
2485 } /* if */
2486 carry += prod;
2487 pos2++;
2488 } while (pos2 < size);
2489 product[pos1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2490 carry >>= BIGDIGIT_SIZE;
2491 carry |= (carry2 & BIGDIGIT_MASK) << BIGDIGIT_SIZE;
2492 carry2 >>= BIGDIGIT_SIZE;
2493 } /* for */
2494 product[pos1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2495 } /* uBigDigitMult */
2496 #endif
2497
2498
2499
uBigDigitMult(const bigDigitType * const factor1,const bigDigitType * const factor2,const memSizeType size,bigDigitType * const product)2500 static void uBigDigitMult (const bigDigitType *const factor1,
2501 const bigDigitType *const factor2, const memSizeType size,
2502 bigDigitType *const product)
2503
2504 {
2505 memSizeType pos1;
2506 memSizeType pos2 = 0;
2507 doubleBigDigitType carry = 0;
2508
2509 /* uBigDigitMult */
2510 do {
2511 carry += (doubleBigDigitType) factor1[0] * factor2[pos2];
2512 product[pos2] = (bigDigitType) (carry & BIGDIGIT_MASK);
2513 carry >>= BIGDIGIT_SIZE;
2514 pos2++;
2515 } while (pos2 < size);
2516 product[size] = (bigDigitType) (carry & BIGDIGIT_MASK);
2517 for (pos1 = 1; pos1 < size; pos1++) {
2518 carry = 0;
2519 pos2 = 0;
2520 do {
2521 carry += (doubleBigDigitType) product[pos1 + pos2] +
2522 (doubleBigDigitType) factor1[pos1] * factor2[pos2];
2523 product[pos1 + pos2] = (bigDigitType) (carry & BIGDIGIT_MASK);
2524 carry >>= BIGDIGIT_SIZE;
2525 pos2++;
2526 } while (pos2 < size);
2527 product[pos1 + size] = (bigDigitType) (carry & BIGDIGIT_MASK);
2528 } /* for */
2529 } /* uBigDigitMult */
2530
2531
2532
uBigKaratsubaMult(const bigDigitType * const factor1,const bigDigitType * const factor2,const memSizeType size,bigDigitType * const product,bigDigitType * const temp)2533 static void uBigKaratsubaMult (const bigDigitType *const factor1,
2534 const bigDigitType *const factor2, const memSizeType size,
2535 bigDigitType *const product, bigDigitType *const temp)
2536
2537 {
2538 memSizeType sizeLo;
2539 memSizeType sizeHi;
2540
2541 /* uBigKaratsubaMult */
2542 /* printf("uBigKaratsubaMult: size=" FMT_U_MEM "\n", size); */
2543 if (size < KARATSUBA_MULT_THRESHOLD) {
2544 uBigDigitMult(factor1, factor2, size, product);
2545 } else {
2546 sizeHi = size >> 1;
2547 sizeLo = size - sizeHi;
2548 uBigDigitAdd(factor1, sizeLo, &factor1[sizeLo], sizeHi, product);
2549 uBigDigitAdd(factor2, sizeLo, &factor2[sizeLo], sizeHi, &product[size]);
2550 uBigKaratsubaMult(product, &product[size], sizeLo + 1, temp, &temp[(sizeLo + 1) << 1]);
2551 uBigKaratsubaMult(factor1, factor2, sizeLo, product, &temp[(sizeLo + 1) << 1]);
2552 uBigKaratsubaMult(&factor1[sizeLo], &factor2[sizeLo], sizeHi, &product[sizeLo << 1],
2553 &temp[(sizeLo + 1) << 1]);
2554 uBigDigitSbtrFrom(temp, (sizeLo + 1) << 1, product, sizeLo << 1);
2555 uBigDigitSbtrFrom(temp, (sizeLo + 1) << 1, &product[sizeLo << 1], sizeHi << 1);
2556 uBigDigitAddTo(&product[sizeLo], sizeLo + (sizeHi << 1), temp, (sizeLo + 1) << 1);
2557 } /* if */
2558 } /* uBigKaratsubaMult */
2559
2560
2561
uBigDigitSquare(const bigDigitType * const big1,const memSizeType size,bigDigitType * const square)2562 static void uBigDigitSquare (const bigDigitType *const big1,
2563 const memSizeType size, bigDigitType *const square)
2564
2565 {
2566 memSizeType pos1;
2567 memSizeType pos2;
2568 doubleBigDigitType carry;
2569 doubleBigDigitType product;
2570 bigDigitType digit;
2571
2572 /* uBigDigitSquare */
2573 digit = big1[0];
2574 carry = (doubleBigDigitType) digit * digit;
2575 square[0] = (bigDigitType) (carry & BIGDIGIT_MASK);
2576 carry >>= BIGDIGIT_SIZE;
2577 if (size == 1) {
2578 square[1] = (bigDigitType) (carry);
2579 } else {
2580 for (pos2 = 1; pos2 < size; pos2++) {
2581 product = (doubleBigDigitType) digit * big1[pos2];
2582 carry += (product << 1) & BIGDIGIT_MASK;
2583 square[pos2] = (bigDigitType) (carry & BIGDIGIT_MASK);
2584 carry >>= BIGDIGIT_SIZE;
2585 carry += product >> (BIGDIGIT_SIZE - 1);
2586 } /* for */
2587 square[pos2] = (bigDigitType) (carry & BIGDIGIT_MASK);
2588 square[pos2 + 1] = (bigDigitType) (carry >> BIGDIGIT_SIZE);
2589 for (pos1 = 1; pos1 < size; pos1++) {
2590 digit = big1[pos1];
2591 carry = (doubleBigDigitType) square[pos1 << 1] +
2592 (doubleBigDigitType) digit * digit;
2593 square[pos1 << 1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2594 carry >>= BIGDIGIT_SIZE;
2595 for (pos2 = pos1 + 1; pos2 < size; pos2++) {
2596 product = (doubleBigDigitType) digit * big1[pos2];
2597 carry += (doubleBigDigitType) square[pos1 + pos2] +
2598 ((product << 1) & BIGDIGIT_MASK);
2599 square[pos1 + pos2] = (bigDigitType) (carry & BIGDIGIT_MASK);
2600 carry >>= BIGDIGIT_SIZE;
2601 carry += product >> (BIGDIGIT_SIZE - 1);
2602 } /* for */
2603 carry += (doubleBigDigitType) square[pos1 + pos2];
2604 square[pos1 + pos2] = (bigDigitType) (carry & BIGDIGIT_MASK);
2605 if (pos1 < size - 1) {
2606 square[pos1 + pos2 + 1] = (bigDigitType) (carry >> BIGDIGIT_SIZE);
2607 } /* if */
2608 } /* for */
2609 } /* if */
2610 } /* uBigDigitSquare */
2611
2612
2613
uBigKaratsubaSquare(const bigDigitType * const big1,const memSizeType size,bigDigitType * const square,bigDigitType * const temp)2614 static void uBigKaratsubaSquare (const bigDigitType *const big1,
2615 const memSizeType size, bigDigitType *const square, bigDigitType *const temp)
2616
2617 {
2618 memSizeType sizeLo;
2619 memSizeType sizeHi;
2620
2621 /* uBigKaratsubaSquare */
2622 /* printf("uBigKaratsubaSquare: size=" FMT_U_MEM "\n", size);); */
2623 if (size < KARATSUBA_SQUARE_THRESHOLD) {
2624 uBigDigitSquare(big1, size, square);
2625 } else {
2626 sizeHi = size >> 1;
2627 sizeLo = size - sizeHi;
2628 uBigDigitAdd(big1, sizeLo, &big1[sizeLo], sizeHi, square);
2629 uBigKaratsubaSquare(square, sizeLo + 1, temp, &temp[(sizeLo + 1) << 1]);
2630 uBigKaratsubaSquare(big1, sizeLo, square, &temp[(sizeLo + 1) << 1]);
2631 uBigKaratsubaSquare(&big1[sizeLo], sizeHi, &square[sizeLo << 1], &temp[(sizeLo + 1) << 1]);
2632 uBigDigitSbtrFrom(temp, (sizeLo + 1) << 1, square, sizeLo << 1);
2633 uBigDigitSbtrFrom(temp, (sizeLo + 1) << 1, &square[sizeLo << 1], sizeHi << 1);
2634 uBigDigitAddTo(&square[sizeLo], sizeLo + (sizeHi << 1), temp, (sizeLo + 1) << 1);
2635 } /* if */
2636 } /* uBigKaratsubaSquare */
2637
2638
uBigMultPositiveWithDigit(const const_bigIntType factor1,const bigDigitType factor2_digit,const bigIntType product)2639 static void uBigMultPositiveWithDigit (const const_bigIntType factor1,
2640 const bigDigitType factor2_digit, const bigIntType product)
2641
2642 {
2643 memSizeType pos;
2644 doubleBigDigitType mult_carry;
2645
2646 /* uBigMultPositiveWithDigit */
2647 mult_carry = (doubleBigDigitType) factor1->bigdigits[0] * factor2_digit;
2648 product->bigdigits[0] = (bigDigitType) (mult_carry & BIGDIGIT_MASK);
2649 mult_carry >>= BIGDIGIT_SIZE;
2650 for (pos = 1; pos < factor1->size; pos++) {
2651 mult_carry += (doubleBigDigitType) factor1->bigdigits[pos] * factor2_digit;
2652 product->bigdigits[pos] = (bigDigitType) (mult_carry & BIGDIGIT_MASK);
2653 mult_carry >>= BIGDIGIT_SIZE;
2654 } /* for */
2655 product->bigdigits[pos] = (bigDigitType) (mult_carry & BIGDIGIT_MASK);
2656 } /* uBigMultPositiveWithDigit */
2657
2658
2659
uBigMultNegativeWithDigit(const const_bigIntType factor1,const bigDigitType factor2_digit,const bigIntType product)2660 static void uBigMultNegativeWithDigit (const const_bigIntType factor1,
2661 const bigDigitType factor2_digit, const bigIntType product)
2662
2663 {
2664 memSizeType pos;
2665 doubleBigDigitType negate_carry = 1;
2666 doubleBigDigitType mult_carry;
2667 doubleBigDigitType product_carry = 1;
2668
2669 /* uBigMultNegativeWithDigit */
2670 negate_carry += ~factor1->bigdigits[0] & BIGDIGIT_MASK;
2671 mult_carry = (negate_carry & BIGDIGIT_MASK) * factor2_digit;
2672 product_carry += ~mult_carry & BIGDIGIT_MASK;
2673 product->bigdigits[0] = (bigDigitType) (product_carry & BIGDIGIT_MASK);
2674 negate_carry >>= BIGDIGIT_SIZE;
2675 mult_carry >>= BIGDIGIT_SIZE;
2676 product_carry >>= BIGDIGIT_SIZE;
2677 for (pos = 1; pos < factor1->size; pos++) {
2678 negate_carry += ~factor1->bigdigits[pos] & BIGDIGIT_MASK;
2679 mult_carry += (negate_carry & BIGDIGIT_MASK) * factor2_digit;
2680 product_carry += ~mult_carry & BIGDIGIT_MASK;
2681 product->bigdigits[pos] = (bigDigitType) (product_carry & BIGDIGIT_MASK);
2682 negate_carry >>= BIGDIGIT_SIZE;
2683 mult_carry >>= BIGDIGIT_SIZE;
2684 product_carry >>= BIGDIGIT_SIZE;
2685 } /* for */
2686 product_carry += ~mult_carry & BIGDIGIT_MASK;
2687 product->bigdigits[pos] = (bigDigitType) (product_carry & BIGDIGIT_MASK);
2688 } /* uBigMultNegativeWithDigit */
2689
2690
2691
uBigMultPositiveWithNegatedDigit(const const_bigIntType factor1,const bigDigitType factor2_digit,const bigIntType product)2692 static void uBigMultPositiveWithNegatedDigit (const const_bigIntType factor1,
2693 const bigDigitType factor2_digit, const bigIntType product)
2694
2695 {
2696 memSizeType pos;
2697 doubleBigDigitType mult_carry;
2698 doubleBigDigitType product_carry = 1;
2699
2700 /* uBigMultPositiveWithNegatedDigit */
2701 mult_carry = (doubleBigDigitType) factor1->bigdigits[0] * factor2_digit;
2702 product_carry += ~mult_carry & BIGDIGIT_MASK;
2703 product->bigdigits[0] = (bigDigitType) (product_carry & BIGDIGIT_MASK);
2704 mult_carry >>= BIGDIGIT_SIZE;
2705 product_carry >>= BIGDIGIT_SIZE;
2706 for (pos = 1; pos < factor1->size; pos++) {
2707 mult_carry += (doubleBigDigitType) factor1->bigdigits[pos] * factor2_digit;
2708 product_carry += ~mult_carry & BIGDIGIT_MASK;
2709 product->bigdigits[pos] = (bigDigitType) (product_carry & BIGDIGIT_MASK);
2710 mult_carry >>= BIGDIGIT_SIZE;
2711 product_carry >>= BIGDIGIT_SIZE;
2712 } /* for */
2713 product_carry += ~mult_carry & BIGDIGIT_MASK;
2714 product->bigdigits[pos] = (bigDigitType) (product_carry & BIGDIGIT_MASK);
2715 } /* uBigMultPositiveWithNegatedDigit */
2716
2717
2718
uBigMultNegativeWithNegatedDigit(const const_bigIntType factor1,const bigDigitType factor2_digit,const bigIntType product)2719 static void uBigMultNegativeWithNegatedDigit (const const_bigIntType factor1,
2720 const bigDigitType factor2_digit, const bigIntType product)
2721
2722 {
2723 memSizeType pos;
2724 doubleBigDigitType negate_carry = 1;
2725 doubleBigDigitType mult_carry;
2726
2727 /* uBigMultNegativeWithNegatedDigit */
2728 negate_carry += ~factor1->bigdigits[0] & BIGDIGIT_MASK;
2729 mult_carry = (negate_carry & BIGDIGIT_MASK) * factor2_digit;
2730 product->bigdigits[0] = (bigDigitType) (mult_carry & BIGDIGIT_MASK);
2731 negate_carry >>= BIGDIGIT_SIZE;
2732 mult_carry >>= BIGDIGIT_SIZE;
2733 for (pos = 1; pos < factor1->size; pos++) {
2734 negate_carry += ~factor1->bigdigits[pos] & BIGDIGIT_MASK;
2735 mult_carry += (negate_carry & BIGDIGIT_MASK) * factor2_digit;
2736 product->bigdigits[pos] = (bigDigitType) (mult_carry & BIGDIGIT_MASK);
2737 negate_carry >>= BIGDIGIT_SIZE;
2738 mult_carry >>= BIGDIGIT_SIZE;
2739 } /* for */
2740 product->bigdigits[pos] = (bigDigitType) (mult_carry & BIGDIGIT_MASK);
2741 } /* uBigMultNegativeWithNegatedDigit */
2742
2743
2744
2745 #ifdef OUT_OF_ORDER
uBigMult(const_bigIntType factor1,const_bigIntType factor2,const bigIntType product)2746 static void uBigMult (const_bigIntType factor1, const_bigIntType factor2,
2747 const bigIntType product)
2748
2749 {
2750 const_bigIntType help_big;
2751 memSizeType pos1;
2752 memSizeType pos2;
2753 doubleBigDigitType carry;
2754 doubleBigDigitType carry2 = 0;
2755 doubleBigDigitType prod;
2756
2757 /* uBigMult */
2758 if (factor2->size > factor1->size) {
2759 help_big = factor1;
2760 factor1 = factor2;
2761 factor2 = help_big;
2762 } /* if */
2763 carry = (doubleBigDigitType) factor1->bigdigits[0] * factor2->bigdigits[0];
2764 product->bigdigits[0] = (bigDigitType) (carry & BIGDIGIT_MASK);
2765 carry >>= BIGDIGIT_SIZE;
2766 if (factor2->size == 1) {
2767 for (pos1 = 1; pos1 < factor1->size; pos1++) {
2768 carry += (doubleBigDigitType) factor1->bigdigits[pos1] * factor2->bigdigits[0];
2769 product->bigdigits[pos1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2770 carry >>= BIGDIGIT_SIZE;
2771 } /* for */
2772 } else {
2773 for (pos1 = 1; pos1 < factor2->size; pos1++) {
2774 pos2 = 0;
2775 do {
2776 prod = (doubleBigDigitType) factor1->bigdigits[pos2] * factor2->bigdigits[pos1 - pos2];
2777 if (unlikely(carry > (doubleBigDigitType) ~prod)) {
2778 carry2++;
2779 } /* if */
2780 carry += prod;
2781 pos2++;
2782 } while (pos2 <= pos1);
2783 product->bigdigits[pos1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2784 carry >>= BIGDIGIT_SIZE;
2785 carry |= (carry2 & BIGDIGIT_MASK) << BIGDIGIT_SIZE;
2786 carry2 >>= BIGDIGIT_SIZE;
2787 } /* for */
2788 for (; pos1 < factor1->size; pos1++) {
2789 pos2 = pos1 - factor2->size + 1;
2790 do {
2791 prod = (doubleBigDigitType) factor1->bigdigits[pos2] * factor2->bigdigits[pos1 - pos2];
2792 if (unlikely(carry > (doubleBigDigitType) ~prod)) {
2793 carry2++;
2794 } /* if */
2795 carry += prod;
2796 pos2++;
2797 } while (pos2 <= pos1);
2798 product->bigdigits[pos1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2799 carry >>= BIGDIGIT_SIZE;
2800 carry |= (carry2 & BIGDIGIT_MASK) << BIGDIGIT_SIZE;
2801 carry2 >>= BIGDIGIT_SIZE;
2802 } /* for */
2803 for (; pos1 < factor1->size + factor2->size - 1; pos1++) {
2804 pos2 = pos1 - factor2->size + 1;
2805 do {
2806 prod = (doubleBigDigitType) factor1->bigdigits[pos2] * factor2->bigdigits[pos1 - pos2];
2807 if (unlikely(carry > (doubleBigDigitType) ~prod)) {
2808 carry2++;
2809 } /* if */
2810 carry += prod;
2811 pos2++;
2812 } while (pos2 < factor1->size);
2813 product->bigdigits[pos1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2814 carry >>= BIGDIGIT_SIZE;
2815 carry |= (carry2 & BIGDIGIT_MASK) << BIGDIGIT_SIZE;
2816 carry2 >>= BIGDIGIT_SIZE;
2817 } /* for */
2818 } /* if */
2819 product->bigdigits[pos1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2820 } /* uBigMult */
2821 #endif
2822
2823
2824
2825 #ifdef OUT_OF_ORDER
uBigMult(const const_bigIntType factor1,const const_bigIntType factor2,const bigIntType product)2826 static void uBigMult (const const_bigIntType factor1, const const_bigIntType factor2,
2827 const bigIntType product)
2828
2829 {
2830 memSizeType pos1;
2831 memSizeType pos2;
2832 memSizeType pos3;
2833 doubleBigDigitType carry;
2834 doubleBigDigitType carry2 = 0;
2835 doubleBigDigitType prod;
2836
2837 /* uBigMult */
2838 carry = (doubleBigDigitType) factor1->bigdigits[0] * factor2->bigdigits[0];
2839 product->bigdigits[0] = (bigDigitType) (carry & BIGDIGIT_MASK);
2840 carry >>= BIGDIGIT_SIZE;
2841 for (pos1 = 1; pos1 < factor1->size + factor2->size - 1; pos1++) {
2842 if (pos1 < factor2->size) {
2843 pos2 = 0;
2844 } else {
2845 pos2 = pos1 - factor2->size + 1;
2846 } /* if */
2847 if (pos1 < factor1->size) {
2848 pos3 = pos1 + 1;
2849 } else {
2850 pos3 = factor1->size;
2851 } /* if */
2852 do {
2853 prod = (doubleBigDigitType) factor1->bigdigits[pos2] * factor2->bigdigits[pos1 - pos2];
2854 /* To avoid overflows of carry + prod it is necessary */
2855 /* to check if carry + prod > DOUBLEBIGDIGIT_MASK which */
2856 /* is equivalent to carry > DOUBLEBIGDIGIT_MASK - prod. */
2857 /* A subtraction can be replaced by adding the negated */
2858 /* value: carry > DOUBLEBIGDIGIT_MASK + ~prod + 1. This */
2859 /* can be simplified to carry > ~prod. */
2860 if (unlikely(carry > (doubleBigDigitType) ~prod)) {
2861 carry2++;
2862 } /* if */
2863 carry += prod;
2864 pos2++;
2865 } while (pos2 < pos3);
2866 product->bigdigits[pos1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2867 carry >>= BIGDIGIT_SIZE;
2868 carry |= (carry2 & BIGDIGIT_MASK) << BIGDIGIT_SIZE;
2869 carry2 >>= BIGDIGIT_SIZE;
2870 } /* for */
2871 product->bigdigits[pos1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2872 } /* uBigMult */
2873 #endif
2874
2875
2876
uBigMult(const const_bigIntType factor1,const const_bigIntType factor2,const bigIntType product)2877 static void uBigMult (const const_bigIntType factor1, const const_bigIntType factor2,
2878 const bigIntType product)
2879
2880 {
2881 memSizeType pos1 = 0;
2882 memSizeType pos2;
2883 doubleBigDigitType carry = 0;
2884
2885 /* uBigMult */
2886 do {
2887 carry += (doubleBigDigitType) factor1->bigdigits[pos1] * factor2->bigdigits[0];
2888 product->bigdigits[pos1] = (bigDigitType) (carry & BIGDIGIT_MASK);
2889 carry >>= BIGDIGIT_SIZE;
2890 pos1++;
2891 } while (pos1 < factor1->size);
2892 product->bigdigits[factor1->size] = (bigDigitType) (carry & BIGDIGIT_MASK);
2893 for (pos2 = 1; pos2 < factor2->size; pos2++) {
2894 carry = 0;
2895 pos1 = 0;
2896 do {
2897 carry += (doubleBigDigitType) product->bigdigits[pos1 + pos2] +
2898 (doubleBigDigitType) factor1->bigdigits[pos1] * factor2->bigdigits[pos2];
2899 product->bigdigits[pos1 + pos2] = (bigDigitType) (carry & BIGDIGIT_MASK);
2900 carry >>= BIGDIGIT_SIZE;
2901 pos1++;
2902 } while (pos1 < factor1->size);
2903 product->bigdigits[factor1->size + pos2] = (bigDigitType) (carry & BIGDIGIT_MASK);
2904 } /* for */
2905 } /* uBigMult */
2906
2907
2908
bigMultAssign1(bigIntType * const big_variable,bigDigitType factor_digit)2909 static void bigMultAssign1 (bigIntType *const big_variable, bigDigitType factor_digit)
2910
2911 {
2912 const_bigIntType big1;
2913 boolType negative = FALSE;
2914 const_bigIntType big1_help = NULL;
2915 memSizeType pos;
2916 doubleBigDigitType carry = 0;
2917 bigIntType product;
2918
2919 /* bigMultAssign1 */
2920 big1 = *big_variable;
2921 if (IS_NEGATIVE(big1->bigdigits[big1->size - 1])) {
2922 negative = TRUE;
2923 big1_help = alloc_positive_copy_of_negative_big(big1);
2924 big1 = big1_help;
2925 if (unlikely(big1_help == NULL)) {
2926 raise_error(MEMORY_ERROR);
2927 return;
2928 } /* if */
2929 } /* if */
2930 if (IS_NEGATIVE(factor_digit)) {
2931 negative = !negative;
2932 /* The unsigned value is negated to avoid a signed integer */
2933 /* overflow if the smallest signed integer is negated. */
2934 factor_digit = -factor_digit;
2935 } /* if */
2936 if (unlikely(!ALLOC_BIG(product, big1->size + 1))) {
2937 raise_error(MEMORY_ERROR);
2938 } else {
2939 for (pos = 0; pos < big1->size; pos++) {
2940 carry += (doubleBigDigitType) big1->bigdigits[pos] * factor_digit;
2941 product->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
2942 carry >>= BIGDIGIT_SIZE;
2943 } /* for */
2944 product->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
2945 product->size = big1->size + 1;
2946 if (negative) {
2947 negate_positive_big(product);
2948 } /* if */
2949 product = normalize(product);
2950 FREE_BIG(*big_variable, (*big_variable)->size);
2951 *big_variable = product;
2952 } /* if */
2953 if (big1_help != NULL) {
2954 FREE_BIG(big1_help, big1_help->size);
2955 } /* if */
2956 } /* bigMultAssign1 */
2957
2958
2959
2960 /**
2961 * Multiply two unsigned big integers with the Karatsuba multiplication.
2962 * @return the product, and NULL if there is not enough memory.
2963 */
uBigMultK(const_bigIntType factor1,const_bigIntType factor2,const boolType negative)2964 static bigIntType uBigMultK (const_bigIntType factor1, const_bigIntType factor2,
2965 const boolType negative)
2966
2967 {
2968 const_bigIntType help_big;
2969 bigIntType factor2_help;
2970 bigIntType temp;
2971 bigIntType product;
2972
2973 /* uBigMultK */
2974 logFunction(printf("uBigMultK(size= " FMT_U_MEM ", size=" FMT_U_MEM ", *)\n",
2975 factor1->size, factor2->size););
2976 if (factor2->size > factor1->size) {
2977 help_big = factor1;
2978 factor1 = factor2;
2979 factor2 = help_big;
2980 } /* if */
2981 if (factor1->size >= KARATSUBA_MULT_THRESHOLD &&
2982 factor2->size >= KARATSUBA_MULT_THRESHOLD) {
2983 if (factor2->size << 1 <= factor1->size) {
2984 if (unlikely(!ALLOC_BIG_SIZE_OK(factor2_help, factor1->size - (factor1->size >> 1)))) {
2985 product = NULL;
2986 } else {
2987 factor2_help->size = factor1->size - (factor1->size >> 1);
2988 memcpy(factor2_help->bigdigits, factor2->bigdigits,
2989 (size_t) factor2->size * sizeof(bigDigitType));
2990 memset(&factor2_help->bigdigits[factor2->size], 0,
2991 (size_t) (factor2_help->size - factor2->size) * sizeof(bigDigitType));
2992 factor2 = factor2_help;
2993 if (likely(ALLOC_BIG(product, (factor1->size >> 1) + (factor2->size << 1)))) {
2994 product->size = (factor1->size >> 1) + (factor2->size << 1);
2995 if (unlikely(!ALLOC_BIG(temp, factor1->size << 2))) {
2996 FREE_BIG(product, (factor1->size >> 1) + (factor2->size << 1));
2997 product = NULL;
2998 } else {
2999 uBigKaratsubaMult(factor1->bigdigits, factor2->bigdigits,
3000 factor1->size >> 1, product->bigdigits, temp->bigdigits);
3001 uBigKaratsubaMult(&factor1->bigdigits[factor1->size >> 1], factor2->bigdigits,
3002 factor2->size, temp->bigdigits,
3003 &temp->bigdigits[factor2->size << 1]);
3004 memset(&product->bigdigits[(factor1->size >> 1) << 1], 0,
3005 (size_t) (product->size - ((factor1->size >> 1) << 1)) * sizeof(bigDigitType));
3006 uBigDigitAddTo(&product->bigdigits[factor1->size >> 1],
3007 product->size - (factor1->size >> 1),
3008 temp->bigdigits, factor2->size << 1);
3009 if (negative) {
3010 negate_positive_big(product);
3011 } /* if */
3012 product = normalize(product);
3013 FREE_BIG(temp, factor1->size << 2);
3014 } /* if */
3015 } /* if */
3016 FREE_BIG(factor2_help, factor1->size - (factor1->size >> 1));
3017 } /* if */
3018 } else {
3019 if (unlikely(!ALLOC_BIG_SIZE_OK(factor2_help, factor1->size))) {
3020 product = NULL;
3021 } else {
3022 factor2_help->size = factor1->size;
3023 memcpy(factor2_help->bigdigits, factor2->bigdigits,
3024 (size_t) factor2->size * sizeof(bigDigitType));
3025 memset(&factor2_help->bigdigits[factor2->size], 0,
3026 (size_t) (factor2_help->size - factor2->size) * sizeof(bigDigitType));
3027 factor2 = factor2_help;
3028 if (likely(ALLOC_BIG(product, factor1->size << 1))) {
3029 if (unlikely(!ALLOC_BIG(temp, factor1->size << 2))) {
3030 FREE_BIG(product, factor1->size << 1);
3031 product = NULL;
3032 } else {
3033 uBigKaratsubaMult(factor1->bigdigits, factor2->bigdigits,
3034 factor1->size, product->bigdigits, temp->bigdigits);
3035 product->size = factor1->size << 1;
3036 if (negative) {
3037 negate_positive_big(product);
3038 } /* if */
3039 product = normalize(product);
3040 FREE_BIG(temp, factor1->size << 2);
3041 } /* if */
3042 } /* if */
3043 FREE_BIG(factor2_help, factor1->size);
3044 } /* if */
3045 } /* if */
3046 } else {
3047 if (likely(ALLOC_BIG(product, factor1->size + factor2->size))) {
3048 product->size = factor1->size + factor2->size;
3049 uBigMult(factor1, factor2, product);
3050 if (negative) {
3051 negate_positive_big(product);
3052 } /* if */
3053 product = normalize(product);
3054 } /* if */
3055 } /* if */
3056 logFunction(printf("uBigMultK -> size= " FMT_U_MEM "\n", product->size););
3057 return product;
3058 } /* uBigMultK */
3059
3060
3061
3062 /**
3063 * Square an unsigned big integer with the Karatsuba multiplication.
3064 * @return the square, and NULL if there is not enough memory.
3065 */
uBigSquareK(const_bigIntType big1)3066 static bigIntType uBigSquareK (const_bigIntType big1)
3067
3068 {
3069 bigIntType temp;
3070 bigIntType square;
3071
3072 /* uBigSquareK */
3073 logFunction(printf("uBigSquareK(size= " FMT_U_MEM ")\n",
3074 big1->size););
3075 if (big1->size >= KARATSUBA_SQUARE_THRESHOLD) {
3076 if (likely(ALLOC_BIG(square, big1->size << 1))) {
3077 if (unlikely(!ALLOC_BIG(temp, big1->size << 2))) {
3078 FREE_BIG(square, big1->size << 1);
3079 square = NULL;
3080 } else {
3081 uBigKaratsubaSquare(big1->bigdigits, big1->size,
3082 square->bigdigits, temp->bigdigits);
3083 square->size = big1->size << 1;
3084 square = normalize(square);
3085 FREE_BIG(temp, big1->size << 2);
3086 } /* if */
3087 } /* if */
3088 } else {
3089 if (likely(ALLOC_BIG(square, big1->size + big1->size))) {
3090 square->size = big1->size + big1->size;
3091 uBigDigitSquare(big1->bigdigits, big1->size, square->bigdigits);
3092 square = normalize(square);
3093 } /* if */
3094 } /* if */
3095 logFunction(printf("uBigSquareK -> size= " FMT_U_MEM "\n", square->size););
3096 return square;
3097 } /* uBigSquareK */
3098
3099
3100
3101 /**
3102 * Computes base to the power of exponent for signed big integers.
3103 * It is assumed that the exponent and base both are >= 1.
3104 * The result variable is set to base or 1 depending on the
3105 * rightmost bit of the exponent. After that the base is
3106 * squared in a loop and every time the corresponding bit of
3107 * the exponent is set the current square is multiplied
3108 * with the result variable. This reduces the number of square
3109 * operations to ld(exponent).
3110 */
bigIPowN(const bigDigitType base,intType exponent)3111 static bigIntType bigIPowN (const bigDigitType base, intType exponent)
3112
3113 {
3114 bigIntType square;
3115 bigIntType big_help;
3116 bigIntType power;
3117
3118 /* bigIPowN */
3119 logFunction(printf("bigIPowN(" FMT_U_DIG ", " FMT_D ")\n",
3120 base, exponent););
3121 if (unlikely(!ALLOC_BIG_SIZE_OK(square, 1))) {
3122 raise_error(MEMORY_ERROR);
3123 power = NULL;
3124 } else if (unlikely(!ALLOC_BIG_SIZE_OK(power, 1))) {
3125 FREE_BIG(square, 1);
3126 raise_error(MEMORY_ERROR);
3127 } else {
3128 square->size = 1;
3129 square->bigdigits[0] = base;
3130 power->size = 1;
3131 if (exponent & 1) {
3132 power->bigdigits[0] = base;
3133 } else {
3134 power->bigdigits[0] = 1;
3135 } /* if */
3136 exponent >>= 1;
3137 while (exponent != 0 && square != NULL && power != NULL) {
3138 big_help = square;
3139 square = uBigSquareK(square);
3140 FREE_BIG(big_help, big_help->size);
3141 if (square != NULL) {
3142 if (exponent & 1) {
3143 big_help = power;
3144 power = uBigMultK(power, square, FALSE);
3145 FREE_BIG(big_help, big_help->size);
3146 } /* if */
3147 exponent >>= 1;
3148 } /* if */
3149 } /* while */
3150 if (unlikely(square == NULL)) {
3151 if (power != NULL) {
3152 FREE_BIG(power, power->size);
3153 } /* if */
3154 raise_error(MEMORY_ERROR);
3155 power = NULL;
3156 } else {
3157 FREE_BIG(square, square->size);
3158 if (unlikely(power == NULL)) {
3159 raise_error(MEMORY_ERROR);
3160 } /* if */
3161 } /* if */
3162 } /* if */
3163 logFunction(printf("bigIPowN --> power->size=" FMT_U_MEM "\n",
3164 power != NULL ? power->size : 0););
3165 return power;
3166 } /* bigIPowN */
3167
3168
3169
3170 /**
3171 * Computes base to the power of exponent for signed big integers.
3172 * It is assumed that the exponent is >= 1.
3173 * The function recognizes the special case of base with a value
3174 * of a power of two. In this case the function bigLog2BaseIPow is
3175 * used.
3176 */
bigIPow1(bigDigitType base,intType exponent)3177 static bigIntType bigIPow1 (bigDigitType base, intType exponent)
3178
3179 {
3180 boolType negative;
3181 unsigned int bit_size;
3182 bigIntType power;
3183
3184 /* bigIPow1 */
3185 logFunction(printf("bigIPow1(" FMT_D_DIG ", " FMT_D ")\n",
3186 base, exponent););
3187 if (base == 0) {
3188 if (unlikely(!ALLOC_BIG_SIZE_OK(power, 1))) {
3189 raise_error(MEMORY_ERROR);
3190 power = NULL;
3191 } else {
3192 power->size = 1;
3193 power->bigdigits[0] = 0;
3194 } /* if */
3195 } else {
3196 if (IS_NEGATIVE(base)) {
3197 /* The unsigned value is negated to avoid a signed integer */
3198 /* overflow if the smallest signed integer is negated. */
3199 base = -base;
3200 negative = (boolType) (exponent & 1);
3201 } else {
3202 negative = FALSE;
3203 } /* if */
3204 bit_size = (unsigned int) (digitMostSignificantBit(base) + 1);
3205 if (base == (bigDigitType) (1 << (bit_size - 1))) {
3206 power = bigLog2BaseIPow((intType) (bit_size - 1), exponent);
3207 if (power != NULL) {
3208 if (negative) {
3209 negate_positive_big(power);
3210 power = normalize(power);
3211 } /* if */
3212 } /* if */
3213 } else {
3214 power = bigIPowN(base, exponent);
3215 if (power != NULL) {
3216 if (negative) {
3217 negate_positive_big(power);
3218 } /* if */
3219 power = normalize(power);
3220 } /* if */
3221 } /* if */
3222 } /* if */
3223 logFunction(printf("bigIPow1 --> power->size=" FMT_U_MEM "\n",
3224 power != NULL ? power->size : 0););
3225 return power;
3226 } /* bigIPow1 */
3227
3228
3229
uBigIsNot0(const const_bigIntType big)3230 static int uBigIsNot0 (const const_bigIntType big)
3231
3232 {
3233 memSizeType pos = 0;
3234
3235 /* uBigIsNot0 */
3236 do {
3237 if (big->bigdigits[pos] != 0) {
3238 return TRUE;
3239 } /* if */
3240 pos++;
3241 } while (pos < big->size);
3242 return FALSE;
3243 } /* uBigIsNot0 */
3244
3245
3246
3247 /**
3248 * Compute the absolute value of a 'bigInteger' number.
3249 * @return the absolute value.
3250 * @exception MEMORY_ERROR Not enough memory to create the result.
3251 */
bigAbs(const const_bigIntType big1)3252 bigIntType bigAbs (const const_bigIntType big1)
3253
3254 {
3255 memSizeType pos;
3256 doubleBigDigitType carry = 1;
3257 memSizeType absoluteValue_size;
3258 bigIntType resized_absoluteValue;
3259 bigIntType absoluteValue;
3260
3261 /* bigAbs */
3262 logFunction(printf("bigAbs(%s)\n", bigHexCStri(big1)););
3263 if (unlikely(!ALLOC_BIG_SIZE_OK(absoluteValue, big1->size))) {
3264 raise_error(MEMORY_ERROR);
3265 } else {
3266 absoluteValue->size = big1->size;
3267 if (IS_NEGATIVE(big1->bigdigits[big1->size - 1])) {
3268 pos = 0;
3269 do {
3270 carry += ~big1->bigdigits[pos] & BIGDIGIT_MASK;
3271 absoluteValue->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3272 carry >>= BIGDIGIT_SIZE;
3273 pos++;
3274 } while (pos < big1->size);
3275 if (IS_NEGATIVE(absoluteValue->bigdigits[pos - 1])) {
3276 absoluteValue_size = absoluteValue->size + 1;
3277 REALLOC_BIG_CHECK_SIZE(resized_absoluteValue, absoluteValue,
3278 big1->size, absoluteValue_size);
3279 if (unlikely(resized_absoluteValue == NULL)) {
3280 FREE_BIG(absoluteValue, big1->size);
3281 raise_error(MEMORY_ERROR);
3282 absoluteValue = NULL;
3283 } else {
3284 absoluteValue = resized_absoluteValue;
3285 COUNT3_BIG(big1->size, absoluteValue->size);
3286 absoluteValue->size = absoluteValue_size;
3287 absoluteValue->bigdigits[big1->size] = 0;
3288 } /* if */
3289 } /* if */
3290 } else {
3291 memcpy(absoluteValue->bigdigits, big1->bigdigits,
3292 (size_t) big1->size * sizeof(bigDigitType));
3293 } /* if */
3294 } /* if */
3295 logFunction(printf("bigAbs --> %s\n", bigHexCStri(absoluteValue)););
3296 return absoluteValue;
3297 } /* bigAbs */
3298
3299
3300
3301 /**
3302 * Compute the absolute value of a 'bigInteger' number.
3303 * Big1 is assumed to be a temporary value which is reused.
3304 * @return the absolute value.
3305 * @exception MEMORY_ERROR Not enough memory to create the result.
3306 */
bigAbsTemp(bigIntType big1)3307 bigIntType bigAbsTemp (bigIntType big1)
3308
3309 {
3310 memSizeType pos;
3311 doubleBigDigitType carry = 1;
3312 boolType negative;
3313 bigIntType resized_big1;
3314
3315 /* bigAbsTemp */
3316 logFunction(printf("bigAbsTemp(%s)\n", bigHexCStri(big1)););
3317 negative = IS_NEGATIVE(big1->bigdigits[big1->size - 1]);
3318 if (negative) {
3319 pos = 0;
3320 do {
3321 carry += ~big1->bigdigits[pos] & BIGDIGIT_MASK;
3322 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3323 carry >>= BIGDIGIT_SIZE;
3324 pos++;
3325 } while (pos < big1->size);
3326 if (IS_NEGATIVE(big1->bigdigits[pos - 1])) {
3327 REALLOC_BIG_CHECK_SIZE(resized_big1, big1, pos, pos + 1);
3328 if (unlikely(resized_big1 == NULL)) {
3329 FREE_BIG(big1, pos);
3330 raise_error(MEMORY_ERROR);
3331 big1 = NULL;
3332 } else {
3333 big1 = resized_big1;
3334 COUNT3_BIG(pos, pos + 1);
3335 big1->size++;
3336 big1->bigdigits[pos] = 0;
3337 } /* if */
3338 } /* if */
3339 } /* if */
3340 logFunction(printf("bigAbsTemp --> %s\n", bigHexCStri(big1)););
3341 return big1;
3342 } /* bigAbsTemp */
3343
3344
3345
3346 /**
3347 * Add two 'bigInteger' numbers.
3348 * The function sorts the two values by size. This way there is a
3349 * loop up to the shorter size and a second loop up to the longer size.
3350 * @return the sum of the two numbers.
3351 * @exception MEMORY_ERROR Not enough memory to create the result.
3352 */
bigAdd(const_bigIntType summand1,const_bigIntType summand2)3353 bigIntType bigAdd (const_bigIntType summand1, const_bigIntType summand2)
3354
3355 {
3356 const_bigIntType help_big;
3357 memSizeType pos;
3358 doubleBigDigitType carry = 0;
3359 doubleBigDigitType summand2_sign;
3360 bigIntType sum;
3361
3362 /* bigAdd */
3363 logFunction(printf("bigAdd(%s,", bigHexCStri(summand1));
3364 printf("%s)\n", bigHexCStri(summand2)););
3365 if (summand2->size > summand1->size) {
3366 help_big = summand1;
3367 summand1 = summand2;
3368 summand2 = help_big;
3369 } /* if */
3370 if (unlikely(!ALLOC_BIG_CHECK_SIZE(sum, summand1->size + 1))) {
3371 raise_error(MEMORY_ERROR);
3372 } else {
3373 pos = 0;
3374 do {
3375 carry += (doubleBigDigitType) summand1->bigdigits[pos] + summand2->bigdigits[pos];
3376 sum->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3377 carry >>= BIGDIGIT_SIZE;
3378 pos++;
3379 } while (pos < summand2->size);
3380 summand2_sign = IS_NEGATIVE(summand2->bigdigits[pos - 1]) ? BIGDIGIT_MASK : 0;
3381 for (; pos < summand1->size; pos++) {
3382 carry += summand1->bigdigits[pos] + summand2_sign;
3383 sum->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3384 carry >>= BIGDIGIT_SIZE;
3385 } /* for */
3386 if (IS_NEGATIVE(summand1->bigdigits[pos - 1])) {
3387 summand2_sign--;
3388 } /* if */
3389 sum->bigdigits[pos] = (bigDigitType) ((carry + summand2_sign) & BIGDIGIT_MASK);
3390 sum->size = pos + 1;
3391 sum = normalize(sum);
3392 } /* if */
3393 logFunction(printf("bigAdd --> %s\n", bigHexCStri(sum)););
3394 return sum;
3395 } /* bigAdd */
3396
3397
3398
3399 /**
3400 * Increment a 'bigInteger' variable by a delta.
3401 * Adds delta to *big_variable. The operation is done in
3402 * place and *big_variable is only resized if necessary.
3403 * If the size of delta is smaller than *big_variable the
3404 * algorithm tries to save computations. Therefore there are
3405 * checks for carry == 0 and carry != 0.
3406 * In case the resizing fails the content of *big_variable
3407 * is freed and *big_variable is set to NULL.
3408 * @param delta The delta to be added to *big_variable.
3409 * @exception MEMORY_ERROR If the resizing of *big_variable fails.
3410 */
bigAddAssign(bigIntType * const big_variable,const const_bigIntType delta)3411 void bigAddAssign (bigIntType *const big_variable, const const_bigIntType delta)
3412
3413 {
3414 bigIntType big1;
3415 memSizeType pos;
3416 memSizeType big1_size;
3417 boolType delta_negative;
3418 doubleBigDigitType carry = 0;
3419 doubleBigDigitType big1_sign;
3420 doubleBigDigitType delta_sign;
3421 bigIntType resized_big1;
3422
3423 /* bigAddAssign */
3424 logFunction(printf("bigAddAssign(%s,", bigHexCStri(*big_variable));
3425 printf("%s)\n", bigHexCStri(delta)););
3426 big1 = *big_variable;
3427 if (big1->size >= delta->size) {
3428 big1_size = big1->size;
3429 big1_sign = IS_NEGATIVE(big1->bigdigits[big1_size - 1]) ? BIGDIGIT_MASK : 0;
3430 /* It is possible that big1 == delta holds. Therefore the check */
3431 /* for negative delta must be done before big1 is changed. */
3432 delta_negative = IS_NEGATIVE(delta->bigdigits[delta->size - 1]);
3433 pos = 0;
3434 do {
3435 carry += (doubleBigDigitType) big1->bigdigits[pos] + delta->bigdigits[pos];
3436 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3437 carry >>= BIGDIGIT_SIZE;
3438 pos++;
3439 } while (pos < delta->size);
3440 if (delta_negative) {
3441 for (; carry == 0 && pos < big1_size; pos++) {
3442 carry = (doubleBigDigitType) big1->bigdigits[pos] + BIGDIGIT_MASK;
3443 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3444 carry >>= BIGDIGIT_SIZE;
3445 } /* for */
3446 carry += BIGDIGIT_MASK;
3447 } else {
3448 for (; carry != 0 && pos < big1_size; pos++) {
3449 carry += big1->bigdigits[pos];
3450 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3451 carry >>= BIGDIGIT_SIZE;
3452 } /* for */
3453 } /* if */
3454 carry += big1_sign;
3455 carry &= BIGDIGIT_MASK;
3456 /* Now the only possible values for carry are 0 and BIGDIGIT_MASK. */
3457 if ((carry != 0 || IS_NEGATIVE(big1->bigdigits[big1_size - 1])) &&
3458 (carry != BIGDIGIT_MASK || !IS_NEGATIVE(big1->bigdigits[big1_size - 1]))) {
3459 REALLOC_BIG_CHECK_SIZE(resized_big1, big1, big1_size, big1_size + 1);
3460 if (unlikely(resized_big1 == NULL)) {
3461 FREE_BIG(big1, big1_size);
3462 *big_variable = NULL;
3463 raise_error(MEMORY_ERROR);
3464 } else {
3465 /* It is possible that big1 == delta holds. Since */
3466 /* 'delta' is not used after realloc() enlarged */
3467 /* 'big1' a correction of delta is not necessary. */
3468 big1 = resized_big1;
3469 COUNT3_BIG(big1_size, big1_size + 1);
3470 big1->size++;
3471 big1->bigdigits[big1_size] = (bigDigitType) (carry);
3472 *big_variable = big1;
3473 } /* if */
3474 } else {
3475 *big_variable = normalize(big1);
3476 } /* if */
3477 } else {
3478 REALLOC_BIG_CHECK_SIZE(resized_big1, big1, big1->size, delta->size + 1);
3479 if (unlikely(resized_big1 == NULL)) {
3480 FREE_BIG(big1, big1->size);
3481 *big_variable = NULL;
3482 raise_error(MEMORY_ERROR);
3483 } else {
3484 big1 = resized_big1;
3485 COUNT3_BIG(big1->size, delta->size + 1);
3486 big1_sign = IS_NEGATIVE(big1->bigdigits[big1->size - 1]) ? BIGDIGIT_MASK : 0;
3487 pos = 0;
3488 do {
3489 carry += (doubleBigDigitType) big1->bigdigits[pos] + delta->bigdigits[pos];
3490 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3491 carry >>= BIGDIGIT_SIZE;
3492 pos++;
3493 } while (pos < big1->size);
3494 delta_sign = IS_NEGATIVE(delta->bigdigits[delta->size - 1]) ? BIGDIGIT_MASK : 0;
3495 for (; pos < delta->size; pos++) {
3496 carry += big1_sign + delta->bigdigits[pos];
3497 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3498 carry >>= BIGDIGIT_SIZE;
3499 } /* for */
3500 carry += big1_sign + delta_sign;
3501 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3502 big1->size = pos + 1;
3503 *big_variable = normalize(big1);
3504 } /* if */
3505 } /* if */
3506 logFunction(printf("bigAddAssign --> %s\n", bigHexCStri(*big_variable)););
3507 } /* bigAddAssign */
3508
3509
3510
3511 /**
3512 * Increment a 'bigInteger' variable by a delta.
3513 * Adds delta to *big_variable. The operation is done in
3514 * place and *big_variable is only resized if necessary.
3515 * In case the resizing fails the content of *big_variable
3516 * is freed and *big_variable is set to NULL.
3517 * @param delta The delta to be added to *big_variable.
3518 * Delta must be in the range of signedBigDigitType.
3519 * @exception MEMORY_ERROR If the resizing of *big_variable fails.
3520 */
bigAddAssignSignedDigit(bigIntType * const big_variable,const intType delta)3521 void bigAddAssignSignedDigit (bigIntType *const big_variable, const intType delta)
3522
3523 {
3524 bigIntType big1;
3525 memSizeType pos;
3526 memSizeType big1_size;
3527 doubleBigDigitType carry = 0;
3528 doubleBigDigitType big1_sign;
3529 bigIntType resized_big1;
3530
3531 /* bigAddAssignSignedDigit */
3532 logFunction(printf("bigAddAssignSignedDigit(%s, " FMT_D ")\n",
3533 bigHexCStri(*big_variable), delta););
3534 big1 = *big_variable;
3535 big1_sign = IS_NEGATIVE(big1->bigdigits[big1->size - 1]) ? BIGDIGIT_MASK : 0;
3536 carry += (doubleBigDigitType) big1->bigdigits[0] + (bigDigitType) (delta & BIGDIGIT_MASK);
3537 big1->bigdigits[0] = (bigDigitType) (carry & BIGDIGIT_MASK);
3538 carry >>= BIGDIGIT_SIZE;
3539 pos = 1;
3540 if (delta < 0) {
3541 for (; carry == 0 && pos < big1->size; pos++) {
3542 carry = (doubleBigDigitType) big1->bigdigits[pos] + BIGDIGIT_MASK;
3543 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3544 carry >>= BIGDIGIT_SIZE;
3545 } /* for */
3546 carry += BIGDIGIT_MASK;
3547 } else {
3548 for (; carry != 0 && pos < big1->size; pos++) {
3549 carry += big1->bigdigits[pos];
3550 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
3551 carry >>= BIGDIGIT_SIZE;
3552 } /* for */
3553 } /* if */
3554 big1_size = big1->size;
3555 carry += big1_sign;
3556 carry &= BIGDIGIT_MASK;
3557 if ((carry != 0 || IS_NEGATIVE(big1->bigdigits[big1_size - 1])) &&
3558 (carry != BIGDIGIT_MASK || !IS_NEGATIVE(big1->bigdigits[big1_size - 1]))) {
3559 REALLOC_BIG_CHECK_SIZE(resized_big1, big1, big1_size, big1_size + 1);
3560 if (unlikely(resized_big1 == NULL)) {
3561 FREE_BIG(big1, big1_size);
3562 *big_variable = NULL;
3563 raise_error(MEMORY_ERROR);
3564 } else {
3565 big1 = resized_big1;
3566 COUNT3_BIG(big1_size, big1_size + 1);
3567 big1->size++;
3568 big1->bigdigits[big1_size] = (bigDigitType) (carry & BIGDIGIT_MASK);
3569 *big_variable = big1;
3570 } /* if */
3571 } else {
3572 *big_variable = normalize(big1);
3573 } /* if */
3574 logFunction(printf("bigAddAssignSignedDigit --> %s\n",
3575 bigHexCStri(*big_variable)););
3576 } /* bigAddAssignSignedDigit */
3577
3578
3579
3580 /**
3581 * Add two 'bigInteger' numbers.
3582 * Summand1 is assumed to be a temporary value which is reused.
3583 * @return the sum of the two numbers in 'summand1'.
3584 */
bigAddTemp(bigIntType summand1,const const_bigIntType summand2)3585 bigIntType bigAddTemp (bigIntType summand1, const const_bigIntType summand2)
3586
3587 { /* bigAddTemp */
3588 bigAddAssign(&summand1, summand2);
3589 return summand1;
3590 } /* bigAddTemp */
3591
3592
3593
bigAnd(const_bigIntType big1,const_bigIntType big2)3594 bigIntType bigAnd (const_bigIntType big1, const_bigIntType big2)
3595
3596 {
3597 const_bigIntType help_big;
3598 memSizeType pos;
3599 bigDigitType big2_sign;
3600 bigIntType result;
3601
3602 /* bigAnd */
3603 logFunction(printf("bigAnd(%s,", bigHexCStri(big1));
3604 printf("%s)\n", bigHexCStri(big2)););
3605 if (big2->size > big1->size) {
3606 help_big = big1;
3607 big1 = big2;
3608 big2 = help_big;
3609 } /* if */
3610 if (unlikely(!ALLOC_BIG_SIZE_OK(result, big1->size))) {
3611 raise_error(MEMORY_ERROR);
3612 } else {
3613 pos = 0;
3614 do {
3615 result->bigdigits[pos] = big1->bigdigits[pos] & big2->bigdigits[pos];
3616 pos++;
3617 } while (pos < big2->size);
3618 big2_sign = IS_NEGATIVE(big2->bigdigits[pos - 1]) ? BIGDIGIT_MASK : 0;
3619 for (; pos < big1->size; pos++) {
3620 result->bigdigits[pos] = big1->bigdigits[pos] & big2_sign;
3621 } /* for */
3622 result->size = pos;
3623 result = normalize(result);
3624 } /* if */
3625 logFunction(printf("bigAnd --> %s\n", bigHexCStri(result)););
3626 return result;
3627 } /* bigAnd */
3628
3629
3630
3631 #ifdef OUT_OF_ORDER
bigBinom(bigIntType n_number,bigIntType k_number)3632 bigIntType bigBinom (bigIntType n_number, bigIntType k_number)
3633
3634 {
3635 bigIntType number;
3636 bigIntType result;
3637
3638 /* bigBinom */
3639 if (2 * k_number > n_number) {
3640 k_number = n_number - k_number;
3641 } /* if */
3642 if (k_number < 0) {
3643 result = 0;
3644 } else if (k_number == 0) {
3645 result = 1;
3646 } else {
3647 result = n_number;
3648 for (number = 2; number <= k_number; number++) {
3649 result *= (n_number - number + 1);
3650 result /= number;
3651 } /* for */
3652 } /* if */
3653 return (intType) result;
3654 } /* bigBinom */
3655 #endif
3656
3657
3658
3659 /**
3660 * Number of bits in the minimum two's-complement representation.
3661 * The high bits equivalent to the sign bit are not part of the
3662 * minimum two's-complement representation.
3663 * @return the number of bits.
3664 * @exception RANGE_ERROR The result does not fit into an integer.
3665 */
bigBitLength(const const_bigIntType big1)3666 intType bigBitLength (const const_bigIntType big1)
3667
3668 {
3669 intType bitLength;
3670
3671 /* bigBitLength */
3672 logFunction(printf("bigBitLength(%s)\n", bigHexCStri(big1)););
3673 if (unlikely(big1->size >= MAX_MEM_INDEX >> BIGDIGIT_LOG2_SIZE)) {
3674 logError(printf("bigBitLength(%s): "
3675 "Result does not fit into an integer.\n",
3676 bigHexCStri(big1)););
3677 raise_error(RANGE_ERROR);
3678 bitLength = 0;
3679 } else {
3680 bitLength = (intType) ((big1->size - 1) << BIGDIGIT_LOG2_SIZE);
3681 if (IS_NEGATIVE(big1->bigdigits[big1->size - 1])) {
3682 bitLength += digitMostSignificantBit(~big1->bigdigits[big1->size - 1]) + 1;
3683 } else {
3684 bitLength += digitMostSignificantBit(big1->bigdigits[big1->size - 1]) + 1;
3685 } /* if */
3686 } /* if */
3687 logFunction(printf("bigBitLength --> " FMT_D "\n", bitLength););
3688 return bitLength;
3689 } /* bigBitLength */
3690
3691
3692
3693 /**
3694 * Compare two 'bigInteger' numbers.
3695 * @return -1, 0 or 1 if the first argument is considered to be
3696 * respectively less than, equal to, or greater than the
3697 * second.
3698 */
bigCmp(const const_bigIntType big1,const const_bigIntType big2)3699 intType bigCmp (const const_bigIntType big1, const const_bigIntType big2)
3700
3701 {
3702 boolType big1_negative;
3703 boolType big2_negative;
3704 memSizeType pos;
3705
3706 /* bigCmp */
3707 pos = big1->size;
3708 big1_negative = IS_NEGATIVE(big1->bigdigits[pos - 1]);
3709 big2_negative = IS_NEGATIVE(big2->bigdigits[big2->size - 1]);
3710 if (big1_negative != big2_negative) {
3711 return big1_negative ? -1 : 1;
3712 } else if (pos != big2->size) {
3713 return (pos < big2->size) != big1_negative ? -1 : 1;
3714 } else {
3715 do {
3716 pos--;
3717 if (big1->bigdigits[pos] != big2->bigdigits[pos]) {
3718 return big1->bigdigits[pos] < big2->bigdigits[pos] ? -1 : 1;
3719 } /* if */
3720 } while (pos > 0);
3721 return 0;
3722 } /* if */
3723 } /* bigCmp */
3724
3725
3726
3727 /**
3728 * Reinterpret the generic parameters as bigIntType and call bigCmp.
3729 * Function pointers in C programs generated by the Seed7 compiler
3730 * may point to this function. This assures correct behaviour even
3731 * if sizeof(genericType) != sizeof(bigIntType).
3732 * @return -1, 0 or 1 if the first argument is considered to be
3733 * respectively less than, equal to, or greater than the
3734 * second.
3735 */
bigCmpGeneric(const genericType value1,const genericType value2)3736 intType bigCmpGeneric (const genericType value1, const genericType value2)
3737
3738 { /* bigCmpGeneric */
3739 return bigCmp(((const_rtlObjectType *) &value1)->value.bigIntValue,
3740 ((const_rtlObjectType *) &value2)->value.bigIntValue);
3741 } /* bigCmpGeneric */
3742
3743
3744
3745 /**
3746 * Compare 'big1' with the bigdigit 'number'.
3747 * The range of 'number' is restricted and it is the job of the
3748 * compiler to assure that 'number' is within the allowed range.
3749 * @param number Number that must be in the range of
3750 * signedBigDigitType.
3751 * @return -1, 0 or 1 if the first argument is considered to be
3752 * respectively less than, equal to, or greater than the
3753 * second.
3754 */
bigCmpSignedDigit(const const_bigIntType big1,intType number)3755 intType bigCmpSignedDigit (const const_bigIntType big1, intType number)
3756
3757 {
3758 intType signumValue;
3759
3760 /* bigCmpSignedDigit */
3761 if (number < 0) {
3762 if (!IS_NEGATIVE(big1->bigdigits[big1->size - 1])) {
3763 signumValue = 1;
3764 } else if (big1->size != 1) {
3765 signumValue = -1;
3766 } else if (big1->bigdigits[0] < (bigDigitType) number) {
3767 signumValue = -1;
3768 } else {
3769 signumValue = big1->bigdigits[0] > (bigDigitType) number;
3770 } /* if */
3771 } else {
3772 if (IS_NEGATIVE(big1->bigdigits[big1->size - 1])) {
3773 signumValue = -1;
3774 } else if (big1->size != 1) {
3775 signumValue = 1;
3776 } else if (big1->bigdigits[0] < (bigDigitType) number) {
3777 signumValue = -1;
3778 } else {
3779 signumValue = big1->bigdigits[0] > (bigDigitType) number;
3780 } /* if */
3781 } /* if */
3782 return signumValue;
3783 } /* bigCmpSignedDigit */
3784
3785
3786
3787 /**
3788 * Assign source to *dest.
3789 * A copy function assumes that *dest contains a legal value.
3790 * @exception MEMORY_ERROR Not enough memory to create dest.
3791 */
bigCpy(bigIntType * const dest,const const_bigIntType source)3792 void bigCpy (bigIntType *const dest, const const_bigIntType source)
3793
3794 {
3795 memSizeType new_size;
3796 bigIntType big_dest;
3797
3798 /* bigCpy */
3799 big_dest = *dest;
3800 new_size = source->size;
3801 if (big_dest->size != new_size) {
3802 if (unlikely(!ALLOC_BIG_SIZE_OK(big_dest, new_size))) {
3803 raise_error(MEMORY_ERROR);
3804 return;
3805 } else {
3806 FREE_BIG(*dest, (*dest)->size);
3807 big_dest->size = new_size;
3808 *dest = big_dest;
3809 } /* if */
3810 } /* if */
3811 /* It is possible that *dest == source holds. The */
3812 /* behavior of memcpy() is undefined if source and */
3813 /* destination areas overlap (or are identical). */
3814 /* Therefore memmove() is used instead of memcpy(). */
3815 memmove(big_dest->bigdigits, source->bigdigits,
3816 (size_t) new_size * sizeof(bigDigitType));
3817 } /* bigCpy */
3818
3819
3820
3821 /**
3822 * Reinterpret the generic parameters as bigIntType and call bigCpy.
3823 * Function pointers in C programs generated by the Seed7 compiler
3824 * may point to this function. This assures correct behaviour even
3825 * if sizeof(genericType) != sizeof(bigIntType).
3826 */
bigCpyGeneric(genericType * const dest,const genericType source)3827 void bigCpyGeneric (genericType *const dest, const genericType source)
3828
3829 { /* bigCpyGeneric */
3830 bigCpy(&((rtlObjectType *) dest)->value.bigIntValue,
3831 ((const_rtlObjectType *) &source)->value.bigIntValue);
3832 } /* bigCpyGeneric */
3833
3834
3835
3836 /**
3837 * Return a copy of source, that can be assigned to a new destination.
3838 * It is assumed that the destination of the assignment is undefined.
3839 * Create functions can be used to initialize Seed7 constants.
3840 * @return a copy of source.
3841 * @exception MEMORY_ERROR Not enough memory to represent the result.
3842 */
bigCreate(const const_bigIntType source)3843 bigIntType bigCreate (const const_bigIntType source)
3844
3845 {
3846 memSizeType new_size;
3847 bigIntType result;
3848
3849 /* bigCreate */
3850 new_size = source->size;
3851 if (unlikely(!ALLOC_BIG_SIZE_OK(result, new_size))) {
3852 raise_error(MEMORY_ERROR);
3853 } else {
3854 result->size = new_size;
3855 memcpy(result->bigdigits, source->bigdigits,
3856 (size_t) new_size * sizeof(bigDigitType));
3857 } /* if */
3858 return result;
3859 } /* bigCreate */
3860
3861
3862
3863 /**
3864 * Generic Create function to be used via function pointers.
3865 * Function pointers in C programs generated by the Seed7 compiler
3866 * may point to this function. This assures correct behaviour even
3867 * if sizeof(genericType) != sizeof(bigIntType).
3868 */
bigCreateGeneric(const genericType source)3869 genericType bigCreateGeneric (const genericType source)
3870
3871 {
3872 rtlObjectType result;
3873
3874 /* bigCreateGeneric */
3875 INIT_GENERIC_PTR(result.value.genericValue);
3876 result.value.bigIntValue =
3877 bigCreate(((const_rtlObjectType *) &source)->value.bigIntValue);
3878 return result.value.genericValue;
3879 } /* bigCreateGeneric */
3880
3881
3882
3883 /**
3884 * Decrement a 'bigInteger' variable.
3885 * Decrements *big_variable by 1. The operation is done in
3886 * place and *big_variable is only enlarged if necessary.
3887 * In case the enlarging fails the old content of *big_variable
3888 * is restored and the exception MEMORY_ERROR is raised.
3889 * This ensures that bigDecr works as a transaction.
3890 * @exception MEMORY_ERROR If the resizing of *big_variable fails.
3891 */
bigDecr(bigIntType * const big_variable)3892 void bigDecr (bigIntType *const big_variable)
3893
3894 {
3895 bigIntType big1;
3896 memSizeType pos;
3897 boolType negative;
3898 bigIntType resized_big1;
3899
3900 /* bigDecr */
3901 logFunction(printf("bigDecr(%s)\n", bigHexCStri(*big_variable)););
3902 big1 = *big_variable;
3903 negative = IS_NEGATIVE(big1->bigdigits[big1->size - 1]);
3904 pos = 0;
3905 if (big1->bigdigits[pos] == 0) {
3906 if (big1->size == 1) {
3907 big1->bigdigits[pos] = BIGDIGIT_MASK;
3908 pos++;
3909 } else {
3910 do {
3911 big1->bigdigits[pos] = BIGDIGIT_MASK;
3912 pos++;
3913 } while (big1->bigdigits[pos] == 0);
3914 /* memset(big1->bigdigits, 0xFF, pos * sizeof(bigDigitType)); */
3915 } /* if */
3916 } /* if */
3917 if (pos < big1->size) {
3918 big1->bigdigits[pos]--;
3919 } /* if */
3920 pos = big1->size;
3921 if (!IS_NEGATIVE(big1->bigdigits[pos - 1])) {
3922 if (negative) {
3923 REALLOC_BIG_CHECK_SIZE(resized_big1, big1, pos, pos + 1);
3924 if (unlikely(resized_big1 == NULL)) {
3925 /* This error situation is very unlikely, but we need to */
3926 /* make sure that 'big_variable' contains a legal value. */
3927 /* We UNDO the change done for 'big_variable' by setting */
3928 /* it to the old value: The highest bit is set to 1 and */
3929 /* the other bits are set to 0. Note that only values */
3930 /* with this pattern need an additional digit if they */
3931 /* are decremented. */
3932 pos--;
3933 big1->bigdigits[pos] = BIGDIGIT_SIGN;
3934 while (pos != 0) {
3935 pos--;
3936 big1->bigdigits[pos] = 0;
3937 } /* while */
3938 raise_error(MEMORY_ERROR);
3939 } else {
3940 big1 = resized_big1;
3941 COUNT3_BIG(pos, pos + 1);
3942 big1->size++;
3943 big1->bigdigits[pos] = BIGDIGIT_MASK;
3944 *big_variable = big1;
3945 } /* if */
3946 } else if (big1->bigdigits[pos - 1] == 0 &&
3947 pos >= 2 && !IS_NEGATIVE(big1->bigdigits[pos - 2])) {
3948 REALLOC_BIG_SIZE_OK(resized_big1, big1, pos, pos - 1);
3949 /* Avoid a MEMORY_ERROR in the strange case */
3950 /* if a 'realloc' which shrinks memory fails. */
3951 if (likely(resized_big1 != NULL)) {
3952 big1 = resized_big1;
3953 *big_variable = big1;
3954 } /* if */
3955 COUNT3_BIG(pos, pos - 1);
3956 big1->size--;
3957 } /* if */
3958 } /* if */
3959 logFunction(printf("bigDecr --> %s\n", bigHexCStri(*big_variable)););
3960 } /* bigDecr */
3961
3962
3963
3964 /**
3965 * Free the memory referred by 'old_bigint'.
3966 * After bigDestr is left 'old_bigint' refers to not existing memory.
3967 * The memory where 'old_bigint' is stored can be freed afterwards.
3968 */
bigDestr(const const_bigIntType old_bigint)3969 void bigDestr (const const_bigIntType old_bigint)
3970
3971 { /* bigDestr */
3972 if (old_bigint != NULL) {
3973 FREE_BIG(old_bigint, old_bigint->size);
3974 } /* if */
3975 } /* bigDestr */
3976
3977
3978
3979 /**
3980 * Generic Destr function to be used via function pointers.
3981 * Function pointers in C programs generated by the Seed7 compiler
3982 * may point to this function. This assures correct behaviour even
3983 * if sizeof(genericType) != sizeof(bigIntType).
3984 */
bigDestrGeneric(const genericType old_value)3985 void bigDestrGeneric (const genericType old_value)
3986
3987 { /* bigDestrGeneric */
3988 bigDestr(((const_rtlObjectType *) &old_value)->value.bigIntValue);
3989 } /* bigDestrGeneric */
3990
3991
3992
3993 /**
3994 * Integer division truncated towards zero.
3995 * The remainder of this division is computed with bigRem.
3996 * The memory for the result is requested and the normalized
3997 * result is returned. If divisor has just one digit or if
3998 * dividend has less digits than divisor the bigDiv1() or
3999 * bigDivSizeLess() functions are called. In the general case
4000 * the absolute values of dividend and divisor are taken. Then
4001 * dividend is extended by one leading zero digit. After that
4002 * dividend and divisor are shifted to the left such that the
4003 * most significant bit of divisor is set. This fulfills the
4004 * preconditions for calling uBigDiv() which does the main
4005 * work of the division.
4006 * @return the quotient of the integer division.
4007 * @exception NUMERIC_ERROR If a division by zero occurs.
4008 */
bigDiv(const const_bigIntType dividend,const const_bigIntType divisor)4009 bigIntType bigDiv (const const_bigIntType dividend, const const_bigIntType divisor)
4010
4011 {
4012 boolType negative = FALSE;
4013 bigIntType dividend_help;
4014 bigIntType divisor_help;
4015 unsigned int shift;
4016 bigIntType quotient;
4017
4018 /* bigDiv */
4019 logFunction(printf("bigDiv(%s, ", bigHexCStri(dividend));
4020 printf("%s)\n", bigHexCStri(divisor)););
4021 if (divisor->size == 1) {
4022 quotient = bigDiv1(dividend, divisor->bigdigits[0]);
4023 } else if (dividend->size < divisor->size) {
4024 quotient = bigDivSizeLess(dividend, divisor);
4025 } else {
4026 if (unlikely(!ALLOC_BIG_CHECK_SIZE(dividend_help, dividend->size + 2))) {
4027 raise_error(MEMORY_ERROR);
4028 return NULL;
4029 } else {
4030 if (IS_NEGATIVE(dividend->bigdigits[dividend->size - 1])) {
4031 negative = TRUE;
4032 positive_copy_of_negative_big(dividend_help, dividend);
4033 } else {
4034 dividend_help->size = dividend->size;
4035 memcpy(dividend_help->bigdigits, dividend->bigdigits,
4036 (size_t) dividend->size * sizeof(bigDigitType));
4037 } /* if */
4038 dividend_help->bigdigits[dividend_help->size] = 0;
4039 dividend_help->size++;
4040 } /* if */
4041 if (unlikely(!ALLOC_BIG_CHECK_SIZE(divisor_help, divisor->size + 1))) {
4042 FREE_BIG(dividend_help, dividend->size + 2);
4043 raise_error(MEMORY_ERROR);
4044 return NULL;
4045 } else {
4046 if (IS_NEGATIVE(divisor->bigdigits[divisor->size - 1])) {
4047 negative = !negative;
4048 positive_copy_of_negative_big(divisor_help, divisor);
4049 } else {
4050 divisor_help->size = divisor->size;
4051 memcpy(divisor_help->bigdigits, divisor->bigdigits,
4052 (size_t) divisor->size * sizeof(bigDigitType));
4053 } /* if */
4054 } /* if */
4055 if (unlikely(!ALLOC_BIG_SIZE_OK(quotient, dividend_help->size - divisor_help->size + 1))) {
4056 FREE_BIG(dividend_help, dividend->size + 2);
4057 FREE_BIG(divisor_help, divisor->size + 1);
4058 raise_error(MEMORY_ERROR);
4059 return NULL;
4060 } else {
4061 quotient->size = dividend_help->size - divisor_help->size + 1;
4062 quotient->bigdigits[quotient->size - 1] = 0;
4063 shift = (unsigned int)
4064 (digitMostSignificantBit(divisor_help->bigdigits[divisor_help->size - 1]) + 1);
4065 if (shift == 0) {
4066 /* The most significant digit of divisor_help is 0. Just ignore it */
4067 dividend_help->size--;
4068 divisor_help->size--;
4069 if (divisor_help->size == 1) {
4070 uBigDiv1(dividend_help, divisor_help->bigdigits[0], quotient);
4071 } else {
4072 uBigDiv(dividend_help, divisor_help, quotient);
4073 } /* if */
4074 } else {
4075 shift = BIGDIGIT_SIZE - shift;
4076 uBigLShift(dividend_help, shift);
4077 uBigLShift(divisor_help, shift);
4078 uBigDiv(dividend_help, divisor_help, quotient);
4079 } /* if */
4080 if (negative) {
4081 negate_positive_big(quotient);
4082 } /* if */
4083 quotient = normalize(quotient);
4084 } /* if */
4085 FREE_BIG(dividend_help, dividend->size + 2);
4086 FREE_BIG(divisor_help, divisor->size + 1);
4087 } /* if */
4088 logFunction(printf("bigDiv --> %s\n", bigHexCStri(quotient)););
4089 return quotient;
4090 } /* bigDiv */
4091
4092
4093
4094 /**
4095 * Integer division truncated towards zero.
4096 * The memory for the quotient is requested and the normalized
4097 * quotient is returned. The memory for the remainder is
4098 * requested and the normalized remainder is assigned to
4099 * *remainderAddr. If divisor has just one digit or if
4100 * dividend has less digits than divisor the bigDivRem1() or
4101 * bigDivRemSizeLess() functions are called. In the general case
4102 * the absolute values of dividend and divisor are taken. Then
4103 * dividend is extended by one leading zero digit. After that
4104 * dividend and divisor are shifted to the left such that the
4105 * most significant bit of divisor is set. This fulfills the
4106 * preconditions for calling uBigDiv() which does the main
4107 * work of the division.
4108 * @return the quotient of the integer division.
4109 * @exception NUMERIC_ERROR If a division by zero occurs.
4110 */
bigDivRem(const const_bigIntType dividend,const const_bigIntType divisor,bigIntType * remainderAddr)4111 bigIntType bigDivRem (const const_bigIntType dividend, const const_bigIntType divisor,
4112 bigIntType *remainderAddr)
4113
4114 {
4115 boolType quotientNegative = FALSE;
4116 boolType remainderNegative = FALSE;
4117 bigIntType divisor_help;
4118 unsigned int shift;
4119 bigIntType quotient;
4120 bigIntType remainder;
4121
4122 /* bigDivRem */
4123 logFunction(printf("bigDivRem(%s, ", bigHexCStri(dividend));
4124 printf("%s, *)\n", bigHexCStri(divisor)););
4125 if (divisor->size == 1) {
4126 quotient = bigDivRem1(dividend, divisor->bigdigits[0], remainderAddr);
4127 } else if (dividend->size < divisor->size) {
4128 quotient = bigDivRemSizeLess(dividend, divisor, remainderAddr);
4129 } else {
4130 if (unlikely(!ALLOC_BIG_CHECK_SIZE(remainder, dividend->size + 2))) {
4131 *remainderAddr = NULL;
4132 raise_error(MEMORY_ERROR);
4133 return NULL;
4134 } else {
4135 if (IS_NEGATIVE(dividend->bigdigits[dividend->size - 1])) {
4136 quotientNegative = TRUE;
4137 remainderNegative = TRUE;
4138 positive_copy_of_negative_big(remainder, dividend);
4139 } else {
4140 remainder->size = dividend->size;
4141 memcpy(remainder->bigdigits, dividend->bigdigits,
4142 (size_t) dividend->size * sizeof(bigDigitType));
4143 } /* if */
4144 remainder->bigdigits[remainder->size] = 0;
4145 remainder->size++;
4146 } /* if */
4147 if (unlikely(!ALLOC_BIG_CHECK_SIZE(divisor_help, divisor->size + 1))) {
4148 FREE_BIG(remainder, dividend->size + 2);
4149 *remainderAddr = NULL;
4150 raise_error(MEMORY_ERROR);
4151 return NULL;
4152 } else {
4153 if (IS_NEGATIVE(divisor->bigdigits[divisor->size - 1])) {
4154 quotientNegative = !quotientNegative;
4155 positive_copy_of_negative_big(divisor_help, divisor);
4156 } else {
4157 divisor_help->size = divisor->size;
4158 memcpy(divisor_help->bigdigits, divisor->bigdigits,
4159 (size_t) divisor->size * sizeof(bigDigitType));
4160 } /* if */
4161 } /* if */
4162 if (unlikely(!ALLOC_BIG_SIZE_OK(quotient, remainder->size - divisor_help->size + 1))) {
4163 FREE_BIG(remainder, dividend->size + 2);
4164 FREE_BIG(divisor_help, divisor->size + 1);
4165 *remainderAddr = NULL;
4166 raise_error(MEMORY_ERROR);
4167 return NULL;
4168 } else {
4169 quotient->size = remainder->size - divisor_help->size + 1;
4170 quotient->bigdigits[quotient->size - 1] = 0;
4171 shift = (unsigned int)
4172 (digitMostSignificantBit(divisor_help->bigdigits[divisor_help->size - 1]) + 1);
4173 if (shift == 0) {
4174 /* The most significant digit of divisor_help is 0. Just ignore it */
4175 remainder->size--;
4176 divisor_help->size--;
4177 if (divisor_help->size == 1) {
4178 remainder->bigdigits[0] = uBigDivRem1(remainder, divisor_help->bigdigits[0], quotient);
4179 memset(&remainder->bigdigits[1], 0,
4180 (size_t) (remainder->size - 1) * sizeof(bigDigitType));
4181 } else {
4182 uBigDiv(remainder, divisor_help, quotient);
4183 } /* if */
4184 remainder->bigdigits[remainder->size] = 0;
4185 divisor_help->size++;
4186 } else {
4187 shift = BIGDIGIT_SIZE - shift;
4188 uBigLShift(remainder, shift);
4189 uBigLShift(divisor_help, shift);
4190 uBigDiv(remainder, divisor_help, quotient);
4191 uBigRShift(remainder, shift);
4192 } /* if */
4193 remainder->bigdigits[dividend->size + 1] = 0;
4194 remainder->size = dividend->size + 2;
4195 if (quotientNegative) {
4196 negate_positive_big(quotient);
4197 } /* if */
4198 quotient = normalize(quotient);
4199 if (remainderNegative) {
4200 negate_positive_big(remainder);
4201 } /* if */
4202 remainder = normalize(remainder);
4203 } /* if */
4204 FREE_BIG(divisor_help, divisor->size + 1);
4205 *remainderAddr = remainder;
4206 } /* if */
4207 logFunction(printf("bigDivRem --> %s", bigHexCStri(quotient));
4208 printf(" (%s)\n", bigHexCStri(*remainderAddr)););
4209 return quotient;
4210 } /* bigDivRem */
4211
4212
4213
4214 /**
4215 * Check if two 'bigInteger' numbers are equal.
4216 * @return TRUE if both numbers are equal,
4217 * FALSE otherwise.
4218 */
bigEq(const const_bigIntType big1,const const_bigIntType big2)4219 boolType bigEq (const const_bigIntType big1, const const_bigIntType big2)
4220
4221 { /* bigEq */
4222 if (big1->size == big2->size &&
4223 memcmp(big1->bigdigits, big2->bigdigits,
4224 (size_t) big1->size * sizeof(bigDigitType)) == 0) {
4225 return TRUE;
4226 } else {
4227 return FALSE;
4228 } /* if */
4229 } /* bigEq */
4230
4231
4232
4233 /**
4234 * Check if 'big1' is equal to the bigdigit 'number'.
4235 * The range of 'number' is restricted and it is the job of the
4236 * compiler to assure that 'number' is within the allowed range.
4237 * @param number Number that must be in the range of
4238 * signedBigDigitType.
4239 * @return TRUE if 'big1' and 'number' are equal,
4240 * FALSE otherwise.
4241 */
bigEqSignedDigit(const const_bigIntType big1,intType number)4242 boolType bigEqSignedDigit (const const_bigIntType big1, intType number)
4243
4244 { /* bigEqSignedDigit */
4245 return big1->size == 1 && big1->bigdigits[0] == (bigDigitType) number;
4246 } /* bigEqSignedDigit */
4247
4248
4249
4250 /**
4251 * Convert a byte buffer (interpreted as big-endian) to a bigInteger.
4252 * @param size Size of the byte buffer to be converted (in bytes).
4253 * @param buffer Byte buffer to be converted. The bytes are interpreted
4254 * as binary big-endian representation with a base of 256.
4255 * @param isSigned Defines if 'buffer' is interpreted as signed value.
4256 * If 'isSigned' is TRUE the twos-complement representation
4257 * is used. In this case the result is negative if the most
4258 * significant byte (the first byte) has an ordinal > BYTE_MAX (=127).
4259 * @return a bigInteger created from the big-endian bytes.
4260 * @exception MEMORY_ERROR Not enough memory to represent the result.
4261 */
bigFromByteBufferBe(const memSizeType size,const const_ustriType buffer,const boolType isSigned)4262 bigIntType bigFromByteBufferBe (const memSizeType size,
4263 const const_ustriType buffer, const boolType isSigned)
4264
4265 {
4266 memSizeType byteIndex;
4267 memSizeType pos;
4268 memSizeType num_bigdigits;
4269 memSizeType result_size;
4270 ucharType buffer2[BIGDIGIT_SIZE >> 3];
4271 bigIntType result;
4272
4273 /* bigFromByteBufferBe */
4274 logFunction(printf("bigFromByteBufferBe(" FMT_U_MEM ", 0x" FMT_X_MEM ", %d)\n",
4275 size, (memSizeType) buffer, isSigned););
4276 if (size == 0) {
4277 num_bigdigits = 0;
4278 result_size = 1;
4279 } else {
4280 num_bigdigits = (size + (BIGDIGIT_SIZE >> 3) - 1) / (BIGDIGIT_SIZE >> 3);
4281 result_size = num_bigdigits;
4282 if (!isSigned && size % (BIGDIGIT_SIZE >> 3) == 0 && buffer[0] > BYTE_MAX) {
4283 /* The number is unsigned, but highest bit is one: */
4284 /* A leading zero bigdigit must be added. */
4285 result_size++;
4286 } /* if */
4287 } /* if */
4288 if (unlikely(!ALLOC_BIG(result, result_size))) {
4289 raise_error(MEMORY_ERROR);
4290 return NULL;
4291 } else {
4292 result->size = result_size;
4293 if (num_bigdigits == 0) {
4294 result->bigdigits[0] = (bigDigitType) 0;
4295 } else {
4296 byteIndex = size;
4297 for (pos = 0; pos < num_bigdigits - 1; pos++) {
4298 #if BIGDIGIT_SIZE == 8
4299 result->bigdigits[pos] = (bigDigitType) buffer[byteIndex - 1];
4300 byteIndex--;
4301 #elif BIGDIGIT_SIZE == 16
4302 result->bigdigits[pos] = ((bigDigitType) buffer[byteIndex - 2]) << 8 |
4303 (bigDigitType) buffer[byteIndex - 1];
4304 byteIndex -= 2;
4305 #elif BIGDIGIT_SIZE == 32
4306 result->bigdigits[pos] = ((bigDigitType) buffer[byteIndex - 4]) << 24 |
4307 ((bigDigitType) buffer[byteIndex - 3]) << 16 |
4308 ((bigDigitType) buffer[byteIndex - 2]) << 8 |
4309 (bigDigitType) buffer[byteIndex - 1];
4310 byteIndex -= 4;
4311 #endif
4312 } /* for */
4313 memcpy(&buffer2[(BIGDIGIT_SIZE >> 3) - byteIndex], buffer, byteIndex);
4314 if (isSigned && buffer[0] > BYTE_MAX) {
4315 memset(buffer2, 0xFF, (BIGDIGIT_SIZE >> 3) - byteIndex);
4316 } else {
4317 memset(buffer2, 0, (BIGDIGIT_SIZE >> 3) - byteIndex);
4318 } /* if */
4319 #if BIGDIGIT_SIZE == 8
4320 result->bigdigits[pos] = (bigDigitType) buffer2[0];
4321 #elif BIGDIGIT_SIZE == 16
4322 result->bigdigits[pos] = ((bigDigitType) buffer2[0]) << 8 |
4323 (bigDigitType) buffer2[1];
4324 #elif BIGDIGIT_SIZE == 32
4325 result->bigdigits[pos] = ((bigDigitType) buffer2[0]) << 24 |
4326 ((bigDigitType) buffer2[1]) << 16 |
4327 ((bigDigitType) buffer2[2]) << 8 |
4328 (bigDigitType) buffer2[3];
4329 #endif
4330 if (num_bigdigits != result_size) {
4331 /* The number is unsigned, but highest bit is one: */
4332 /* A leading zero bigdigit must be added. */
4333 result->bigdigits[num_bigdigits] = (bigDigitType) 0;
4334 } /* if */
4335 } /* if */
4336 } /* if */
4337 result = normalize(result);
4338 logFunction(printf("bigFromByteBufferBe --> %s\n", bigHexCStri(result)););
4339 return result;
4340 } /* bigFromByteBufferBe */
4341
4342
4343
4344 /**
4345 * Convert a byte buffer (interpreted as little-endian) to a bigInteger.
4346 * @param size Size of the byte buffer to be converted (in bytes).
4347 * @param buffer Byte buffer to be converted. The bytes are interpreted
4348 * as binary little-endian representation with a base of 256.
4349 * @param isSigned Defines if 'buffer' is interpreted as signed value.
4350 * If 'isSigned' is TRUE the twos-complement representation
4351 * is used. In this case the result is negative if the most
4352 * significant byte (the last byte) has an ordinal > BYTE_MAX (=127).
4353 * @return a bigInteger created from the little-endian bytes.
4354 * @exception MEMORY_ERROR Not enough memory to represent the result.
4355 */
bigFromByteBufferLe(const memSizeType size,const const_ustriType buffer,const boolType isSigned)4356 bigIntType bigFromByteBufferLe (const memSizeType size,
4357 const const_ustriType buffer, const boolType isSigned)
4358
4359 {
4360 memSizeType byteIndex;
4361 memSizeType pos;
4362 memSizeType num_bigdigits;
4363 memSizeType result_size;
4364 ucharType buffer2[BIGDIGIT_SIZE >> 3];
4365 bigIntType result;
4366
4367 /* bigFromByteBufferLe */
4368 logFunction(printf("bigFromByteBufferLe(" FMT_U_MEM ", 0x" FMT_X_MEM ", %d)\n",
4369 size, (memSizeType) buffer, isSigned););
4370 if (size == 0) {
4371 num_bigdigits = 0;
4372 result_size = 1;
4373 } else {
4374 num_bigdigits = (size + (BIGDIGIT_SIZE >> 3) - 1) / (BIGDIGIT_SIZE >> 3);
4375 result_size = num_bigdigits;
4376 if (!isSigned && buffer[size - 1] > BYTE_MAX) {
4377 /* The number is unsigned, but highest bit is one: */
4378 /* A leading zero bigdigit must be added. */
4379 result_size++;
4380 } /* if */
4381 } /* if */
4382 if (unlikely(!ALLOC_BIG(result, result_size))) {
4383 raise_error(MEMORY_ERROR);
4384 return NULL;
4385 } else {
4386 result->size = result_size;
4387 if (num_bigdigits == 0) {
4388 result->bigdigits[0] = (bigDigitType) 0;
4389 } else {
4390 byteIndex = 0;
4391 for (pos = 0; pos < num_bigdigits - 1; pos++) {
4392 #if BIGDIGIT_SIZE == 8
4393 result->bigdigits[pos] = (bigDigitType) buffer[byteIndex];
4394 byteIndex++;
4395 #elif BIGDIGIT_SIZE == 16
4396 result->bigdigits[pos] = ((bigDigitType) buffer[byteIndex + 1]) << 8 |
4397 (bigDigitType) buffer[byteIndex];
4398 byteIndex += 2;
4399 #elif BIGDIGIT_SIZE == 32
4400 result->bigdigits[pos] = ((bigDigitType) buffer[byteIndex + 3]) << 24 |
4401 ((bigDigitType) buffer[byteIndex + 2]) << 16 |
4402 ((bigDigitType) buffer[byteIndex + 1]) << 8 |
4403 (bigDigitType) buffer[byteIndex];
4404 byteIndex += 4;
4405 #endif
4406 } /* for */
4407 memcpy(buffer2, &buffer[byteIndex], size - byteIndex);
4408 if (isSigned && buffer[size - 1] > BYTE_MAX) {
4409 memset(&buffer2[size - byteIndex], 0xFF, (BIGDIGIT_SIZE >> 3) - (size - byteIndex));
4410 } else {
4411 memset(&buffer2[size - byteIndex], 0, (BIGDIGIT_SIZE >> 3) - (size - byteIndex));
4412 } /* if */
4413 #if BIGDIGIT_SIZE == 8
4414 result->bigdigits[pos] = (bigDigitType) buffer2[0];
4415 #elif BIGDIGIT_SIZE == 16
4416 result->bigdigits[pos] = ((bigDigitType) buffer2[1]) << 8 |
4417 (bigDigitType) buffer2[0];
4418 #elif BIGDIGIT_SIZE == 32
4419 result->bigdigits[pos] = ((bigDigitType) buffer2[3]) << 24 |
4420 ((bigDigitType) buffer2[2]) << 16 |
4421 ((bigDigitType) buffer2[1]) << 8 |
4422 (bigDigitType) buffer2[0];
4423 #endif
4424 if (num_bigdigits != result_size) {
4425 /* The number is unsigned, but highest bit is one: */
4426 /* A leading zero bigdigit must be added. */
4427 result->bigdigits[num_bigdigits] = (bigDigitType) 0;
4428 } /* if */
4429 } /* if */
4430 } /* if */
4431 result = normalize(result);
4432 logFunction(printf("bigFromByteBufferLe --> %s\n", bigHexCStri(result)););
4433 return result;
4434 } /* bigFromByteBufferLe */
4435
4436
4437
4438 /**
4439 * Convert a bstring (interpreted as big-endian) to a bigInteger.
4440 * @param bstri Bstring to be converted. The bytes are interpreted
4441 * as binary big-endian representation with a base of 256.
4442 * @param isSigned Defines if 'bstri' is interpreted as signed value.
4443 * If 'isSigned' is TRUE the twos-complement representation
4444 * is used. In this case the result is negative if the most
4445 * significant byte (the first byte) has an ordinal > BYTE_MAX (=127).
4446 * @return a bigInteger created from the big-endian bytes.
4447 */
bigFromBStriBe(const const_bstriType bstri,const boolType isSigned)4448 bigIntType bigFromBStriBe (const const_bstriType bstri, const boolType isSigned)
4449
4450 { /* bigFromBStriBe */
4451 logFunction(printf("bigFromBStriBe(\"%s\", %d)\n",
4452 bstriAsUnquotedCStri(bstri), isSigned););
4453 return bigFromByteBufferBe(bstri->size, bstri->mem, isSigned);
4454 } /* bigFromBStriBe */
4455
4456
4457
4458 /**
4459 * Convert a bstring (interpreted as little-endian) to a bigInteger.
4460 * @param bstri Bstring to be converted. The bytes are interpreted
4461 * as binary little-endian representation with a base of 256.
4462 * @param isSigned Defines if 'bstri' is interpreted as signed value.
4463 * If 'isSigned' is TRUE the twos-complement representation
4464 * is used. In this case the result is negative if the most
4465 * significant byte (the last byte) has an ordinal > BYTE_MAX (=127).
4466 * @return a bigInteger created from the little-endian bytes.
4467 */
bigFromBStriLe(const const_bstriType bstri,const boolType isSigned)4468 bigIntType bigFromBStriLe (const const_bstriType bstri, const boolType isSigned)
4469
4470 { /* bigFromBStriLe */
4471 logFunction(printf("bigFromBStriLe(\"%s\", %d)\n",
4472 bstriAsUnquotedCStri(bstri), isSigned););
4473 return bigFromByteBufferLe(bstri->size, bstri->mem, isSigned);
4474 } /* bigFromBStriLe */
4475
4476
4477
4478 /**
4479 * Convert an int32Type number to 'bigInteger'.
4480 * @return the bigInteger result of the conversion.
4481 * @exception MEMORY_ERROR Not enough memory to represent the result.
4482 */
bigFromInt32(int32Type number)4483 bigIntType bigFromInt32 (int32Type number)
4484
4485 {
4486 memSizeType result_size;
4487 bigIntType result;
4488
4489 /* bigFromInt32 */
4490 logFunction(printf("bigFromInt32(" FMT_D32 ")\n", number););
4491 #if BIGDIGIT_SIZE < 32
4492 result_size = sizeof(int32Type) / (BIGDIGIT_SIZE >> 3);
4493 #else
4494 result_size = 1;
4495 #endif
4496 if (unlikely(!ALLOC_BIG_SIZE_OK(result, result_size))) {
4497 raise_error(MEMORY_ERROR);
4498 } else {
4499 result->size = result_size;
4500 #if BIGDIGIT_SIZE <= 32
4501 result->bigdigits[0] = (bigDigitType) (((uint32Type) number) & BIGDIGIT_MASK);
4502 #if BIGDIGIT_SIZE < 32
4503 {
4504 memSizeType pos;
4505
4506 for (pos = 1; pos < result_size; pos++) {
4507 number >>= BIGDIGIT_SIZE;
4508 result->bigdigits[pos] = (bigDigitType) (((uint32Type) number) & BIGDIGIT_MASK);
4509 } /* for */
4510 }
4511 #endif
4512 #else
4513 if (number < 0) {
4514 result->bigdigits[0] = (bigDigitType) ((uint32Type) number) | (BIGDIGIT_MASK ^ 0xFFFFFFFF);
4515 } else {
4516 result->bigdigits[0] = (bigDigitType) ((uint32Type) number);
4517 } /* if */
4518 #endif
4519 #if BIGDIGIT_SIZE < 32
4520 result = normalize(result);
4521 #endif
4522 } /* if */
4523 logFunction(printf("bigFromInt32 --> %s\n", bigHexCStri(result)););
4524 return result;
4525 } /* bigFromInt32 */
4526
4527
4528
4529 #ifdef INT64TYPE
4530 /**
4531 * Convert an int64Type number to 'bigInteger'.
4532 * @return the bigInteger result of the conversion.
4533 * @exception MEMORY_ERROR Not enough memory to represent the result.
4534 */
bigFromInt64(int64Type number)4535 bigIntType bigFromInt64 (int64Type number)
4536
4537 {
4538 memSizeType pos;
4539 memSizeType result_size;
4540 bigIntType result;
4541
4542 /* bigFromInt64 */
4543 logFunction(printf("bigFromInt64(" FMT_D64 ")\n", number););
4544 result_size = sizeof(int64Type) / (BIGDIGIT_SIZE >> 3);
4545 if (unlikely(!ALLOC_BIG_SIZE_OK(result, result_size))) {
4546 raise_error(MEMORY_ERROR);
4547 } else {
4548 result->size = result_size;
4549 for (pos = 0; pos < result_size; pos++) {
4550 result->bigdigits[pos] = (bigDigitType) (number & BIGDIGIT_MASK);
4551 number >>= BIGDIGIT_SIZE;
4552 } /* for */
4553 result = normalize(result);
4554 } /* if */
4555 logFunction(printf("bigFromInt64 --> %s\n", bigHexCStri(result)););
4556 return result;
4557 } /* bigFromInt64 */
4558 #endif
4559
4560
4561
4562 /**
4563 * Convert an uint32Type number to 'bigInteger'.
4564 * @return the bigInteger result of the conversion.
4565 * @exception MEMORY_ERROR Not enough memory to represent the result.
4566 */
bigFromUInt32(uint32Type number)4567 bigIntType bigFromUInt32 (uint32Type number)
4568
4569 {
4570 memSizeType result_size;
4571 bigIntType result;
4572
4573 /* bigFromUInt32 */
4574 logFunction(printf("bigFromUInt32(" FMT_U32 ")\n", number););
4575 #if BIGDIGIT_SIZE == 32
4576 if (number > UINT32_SUFFIX(2147483647)) {
4577 result_size = 2;
4578 } else {
4579 result_size = 1;
4580 } /* if */
4581 #elif BIGDIGIT_SIZE == 16
4582 if (number > UINT32_SUFFIX(2147483647)) {
4583 result_size = 3;
4584 } else if (number > UINT32_SUFFIX(32767)) {
4585 result_size = 2;
4586 } else {
4587 result_size = 1;
4588 } /* if */
4589 #elif BIGDIGIT_SIZE == 8
4590 if (number > UINT32_SUFFIX(2147483647)) {
4591 result_size = 5;
4592 } else if (number > UINT32_SUFFIX(8388607)) {
4593 result_size = 4;
4594 } else if (number > UINT32_SUFFIX(32767)) {
4595 result_size = 3;
4596 } else if (number > UINT32_SUFFIX(127)) {
4597 result_size = 2;
4598 } else {
4599 result_size = 1;
4600 } /* if */
4601 #endif
4602 if (unlikely(!ALLOC_BIG_SIZE_OK(result, result_size))) {
4603 raise_error(MEMORY_ERROR);
4604 } else {
4605 result->size = result_size;
4606 if (result_size == sizeof(uint32Type) / (BIGDIGIT_SIZE >> 3) + 1) {
4607 result_size--;
4608 result->bigdigits[result_size] = (bigDigitType) 0;
4609 } /* if */
4610 result->bigdigits[0] = (bigDigitType) (number & BIGDIGIT_MASK);
4611 #if BIGDIGIT_SIZE < 32
4612 {
4613 memSizeType pos;
4614
4615 for (pos = 1; pos < result_size; pos++) {
4616 number >>= BIGDIGIT_SIZE;
4617 result->bigdigits[pos] = (bigDigitType) (number & BIGDIGIT_MASK);
4618 } /* for */
4619 }
4620 #endif
4621 } /* if */
4622 logFunction(printf("bigFromUInt32 --> %s\n", bigHexCStri(result)););
4623 return result;
4624 } /* bigFromUInt32 */
4625
4626
4627
4628 #ifdef INT64TYPE
4629 /**
4630 * Convert an uint64Type number to 'bigInteger'.
4631 * @return the bigInteger result of the conversion.
4632 * @exception MEMORY_ERROR Not enough memory to represent the result.
4633 */
bigFromUInt64(uint64Type number)4634 bigIntType bigFromUInt64 (uint64Type number)
4635
4636 {
4637 memSizeType pos;
4638 memSizeType result_size;
4639 bigIntType result;
4640
4641 /* bigFromUInt64 */
4642 logFunction(printf("bigFromUInt64(" FMT_U64 ")\n", number););
4643 #if BIGDIGIT_SIZE == 32
4644 if (number > UINT64_SUFFIX(9223372036854775807)) {
4645 result_size = 3;
4646 } else if (number > UINT64_SUFFIX(2147483647)) {
4647 result_size = 2;
4648 } else {
4649 result_size = 1;
4650 } /* if */
4651 #elif BIGDIGIT_SIZE == 16
4652 if (number > UINT64_SUFFIX(9223372036854775807)) {
4653 result_size = 5;
4654 } else if (number > UINT64_SUFFIX(140737488355327)) {
4655 result_size = 4;
4656 } else if (number > UINT64_SUFFIX(2147483647)) {
4657 result_size = 3;
4658 } else if (number > UINT64_SUFFIX(32767)) {
4659 result_size = 2;
4660 } else {
4661 result_size = 1;
4662 } /* if */
4663 #elif BIGDIGIT_SIZE == 8
4664 if (number > UINT64_SUFFIX(9223372036854775807)) {
4665 result_size = 9;
4666 } else if (number > UINT64_SUFFIX(36028797018963967)) {
4667 result_size = 8;
4668 } else if (number > UINT64_SUFFIX(140737488355327)) {
4669 result_size = 7;
4670 } else if (number > UINT64_SUFFIX(549755813887)) {
4671 result_size = 6;
4672 } else if (number > UINT64_SUFFIX(2147483647)) {
4673 result_size = 5;
4674 } else if (number > UINT64_SUFFIX(8388607)) {
4675 result_size = 4;
4676 } else if (number > UINT64_SUFFIX(32767)) {
4677 result_size = 3;
4678 } else if (number > UINT64_SUFFIX(127)) {
4679 result_size = 2;
4680 } else {
4681 result_size = 1;
4682 } /* if */
4683 #endif
4684 if (unlikely(!ALLOC_BIG_SIZE_OK(result, result_size))) {
4685 raise_error(MEMORY_ERROR);
4686 } else {
4687 result->size = result_size;
4688 if (result_size == sizeof(uint64Type) / (BIGDIGIT_SIZE >> 3) + 1) {
4689 result_size--;
4690 result->bigdigits[result_size] = (bigDigitType) 0;
4691 } /* if */
4692 result->bigdigits[0] = (bigDigitType) (number & BIGDIGIT_MASK);
4693 for (pos = 1; pos < result_size; pos++) {
4694 number >>= BIGDIGIT_SIZE;
4695 result->bigdigits[pos] = (bigDigitType) (number & BIGDIGIT_MASK);
4696 } /* for */
4697 } /* if */
4698 logFunction(printf("bigFromUInt64 --> %s\n", bigHexCStri(result)););
4699 return result;
4700 } /* bigFromUInt64 */
4701 #endif
4702
4703
4704
4705 /**
4706 * Compute the greatest common divisor of two 'bigInteger' numbers.
4707 * @return the greatest common divisor of the two numbers.
4708 * The greatest common divisor is positive or zero.
4709 */
bigGcd(const const_bigIntType big1,const const_bigIntType big2)4710 bigIntType bigGcd (const const_bigIntType big1,
4711 const const_bigIntType big2)
4712
4713 {
4714 bigIntType big1_help;
4715 bigIntType big2_help;
4716 intType lowestSetBitA;
4717 intType shift;
4718 bigIntType help_big;
4719 bigIntType gcd;
4720
4721 /* bigGcd */
4722 logFunction(printf("bigGcd(%s,", bigHexCStri(big1));
4723 printf("%s)\n", bigHexCStri(big2)););
4724 if (big1->size == 1 && big1->bigdigits[0] == 0) {
4725 gcd = bigAbs(big2);
4726 } else if (big2->size == 1 && big2->bigdigits[0] == 0) {
4727 gcd = bigAbs(big1);
4728 } else if (unlikely((big1_help = bigAbs(big1)) == NULL)) {
4729 /* An exception was raised in bigAbs(). */
4730 gcd = NULL;
4731 } else if (unlikely((big2_help = bigAbs(big2)) == NULL)) {
4732 /* An exception was raised in bigAbs(). */
4733 bigDestr(big1_help);
4734 gcd = NULL;
4735 } else {
4736 if ((big1_help->size > big2_help->size &&
4737 big1_help->size - big2_help->size > 10) ||
4738 (big1_help->size < big2_help->size &&
4739 big2_help->size - big1_help->size > 10)) {
4740 while (big1_help->size != 1 || big1_help->bigdigits[0] != 0) {
4741 help_big = bigRem(big2_help, big1_help);
4742 bigDestr(big2_help);
4743 big2_help = big1_help;
4744 big1_help = help_big;
4745 } /* while */
4746 gcd = big2_help;
4747 bigDestr(big1_help);
4748 } else {
4749 lowestSetBitA = bigLowestSetBit(big1_help);
4750 shift = bigLowestSetBit(big2_help);
4751 if (lowestSetBitA < shift) {
4752 shift = lowestSetBitA;
4753 } /* if */
4754 bigRShiftAssign(&big1_help, lowestSetBitA);
4755 do {
4756 bigRShiftAssign(&big2_help, bigLowestSetBit(big2_help));
4757 if (bigCmp(big1_help, big2_help) < 0) {
4758 bigSbtrAssign(&(big2_help), big1_help);
4759 } else {
4760 help_big = bigSbtr(big1_help, big2_help);
4761 bigDestr(big1_help);
4762 big1_help = big2_help;
4763 big2_help = help_big;
4764 } /* if */
4765 } while (big2_help->size != 1 || big2_help->bigdigits[0] != 0);
4766 bigLShiftAssign(&big1_help, shift);
4767 gcd = big1_help;
4768 bigDestr(big2_help);
4769 } /* if */
4770 } /* if */
4771 logFunction(printf("bigGcd -->%s\n", bigHexCStri(gcd)););
4772 return gcd;
4773 } /* bigGcd */
4774
4775
4776
4777 /**
4778 * Compute the hash value of a 'bigInteger' number.
4779 * @return the hash value.
4780 */
bigHashCode(const const_bigIntType big1)4781 intType bigHashCode (const const_bigIntType big1)
4782
4783 {
4784 intType hashCode;
4785
4786 /* bigHashCode */
4787 hashCode = (intType)
4788 (big1->bigdigits[0] << 5 ^ big1->size << 3 ^ big1->bigdigits[big1->size - 1]);
4789 return hashCode;
4790 } /* bigHashCode */
4791
4792
4793
4794 /**
4795 * Increment a 'bigInteger' variable.
4796 * Increments *big_variable by 1. The operation is done in
4797 * place and *big_variable is only enlarged if necessary.
4798 * In case the enlarging fails the old content of *big_variable
4799 * is restored and the exception MEMORY_ERROR is raised.
4800 * This ensures that bigIncr works as a transaction.
4801 * @exception MEMORY_ERROR If the resizing of *big_variable fails.
4802 */
bigIncr(bigIntType * const big_variable)4803 void bigIncr (bigIntType *const big_variable)
4804
4805 {
4806 bigIntType big1;
4807 memSizeType pos = 0;
4808 boolType negative;
4809 bigIntType resized_big1;
4810
4811 /* bigIncr */
4812 logFunction(printf("bigIncr(%s)\n", bigHexCStri(*big_variable)););
4813 big1 = *big_variable;
4814 negative = IS_NEGATIVE(big1->bigdigits[big1->size - 1]);
4815 if (big1->bigdigits[pos] == BIGDIGIT_MASK) {
4816 if (big1->size == 1) {
4817 big1->bigdigits[pos] = 0;
4818 pos++;
4819 } else {
4820 do {
4821 big1->bigdigits[pos] = 0;
4822 pos++;
4823 } while (big1->bigdigits[pos] == BIGDIGIT_MASK);
4824 /* memset(big1->bigdigits, 0, pos * sizeof(bigDigitType)); */
4825 } /* if */
4826 } /* if */
4827 if (pos < big1->size) {
4828 big1->bigdigits[pos]++;
4829 } /* if */
4830 pos = big1->size;
4831 if (IS_NEGATIVE(big1->bigdigits[pos - 1])) {
4832 if (!negative) {
4833 REALLOC_BIG_CHECK_SIZE(resized_big1, big1, pos, pos + 1);
4834 if (unlikely(resized_big1 == NULL)) {
4835 /* This error situation is very unlikely, but we need to */
4836 /* make sure that 'big_variable' contains a legal value. */
4837 /* We UNDO the change done for 'big_variable' by setting */
4838 /* it to the old value: The highest bit is set to 0 and */
4839 /* the other bits are set to 1. Note that only values */
4840 /* with this pattern need an additional digit if they */
4841 /* are incremented. */
4842 pos--;
4843 big1->bigdigits[pos] = BIGDIGIT_MASK ^ BIGDIGIT_SIGN;
4844 while (pos != 0) {
4845 pos--;
4846 big1->bigdigits[pos] = BIGDIGIT_MASK;
4847 } /* while */
4848 raise_error(MEMORY_ERROR);
4849 } else {
4850 big1 = resized_big1;
4851 COUNT3_BIG(pos, pos + 1);
4852 big1->size++;
4853 big1->bigdigits[pos] = 0;
4854 *big_variable = big1;
4855 } /* if */
4856 } else if (big1->bigdigits[pos - 1] == BIGDIGIT_MASK &&
4857 pos >= 2 && IS_NEGATIVE(big1->bigdigits[pos - 2])) {
4858 REALLOC_BIG_SIZE_OK(resized_big1, big1, pos, pos - 1);
4859 /* Avoid a MEMORY_ERROR in the strange case */
4860 /* if a 'realloc' which shrinks memory fails. */
4861 if (likely(resized_big1 != NULL)) {
4862 big1 = resized_big1;
4863 *big_variable = big1;
4864 } /* if */
4865 COUNT3_BIG(pos, pos - 1);
4866 big1->size--;
4867 } /* if */
4868 } /* if */
4869 logFunction(printf("bigIncr --> %s\n", bigHexCStri(*big_variable)););
4870 } /* bigIncr */
4871
4872
4873
4874 /**
4875 * Compute the exponentiation of a 'bigInteger' base with an integer exponent.
4876 * The result variable is set to base or 1 depending on the
4877 * rightmost bit of the exponent. After that the base is
4878 * squared in a loop and every time the corresponding bit of
4879 * the exponent is set the current square is multiplied
4880 * with the result variable. This reduces the number of square
4881 * operations to ld(exponent).
4882 * @return the result of the exponentiation.
4883 * @exception NUMERIC_ERROR If the exponent is negative.
4884 */
bigIPow(const const_bigIntType base,intType exponent)4885 bigIntType bigIPow (const const_bigIntType base, intType exponent)
4886
4887 {
4888 boolType negative = FALSE;
4889 bigIntType square;
4890 bigIntType big_help;
4891 bigIntType power;
4892
4893 /* bigIPow */
4894 logFunction(printf("bigIPow(%s, " FMT_D ")\n",
4895 bigHexCStri(base), exponent););
4896 if (exponent <= 1) {
4897 if (exponent == 0) {
4898 if (unlikely(!ALLOC_BIG_SIZE_OK(power, 1))) {
4899 raise_error(MEMORY_ERROR);
4900 } else {
4901 power->size = 1;
4902 power->bigdigits[0] = 1;
4903 } /* if */
4904 } else if (exponent == 1) {
4905 power = bigCreate(base);
4906 } else {
4907 logError(printf("bigIPow(%s, " FMT_D "): "
4908 "Exponent is negative.\n",
4909 bigHexCStri(base), exponent););
4910 raise_error(NUMERIC_ERROR);
4911 power = NULL;
4912 } /* if */
4913 } else if (base->size == 1) {
4914 power = bigIPow1(base->bigdigits[0], exponent);
4915 } else if (unlikely(!ALLOC_BIG_CHECK_SIZE(square, base->size + 1))) {
4916 raise_error(MEMORY_ERROR);
4917 power = NULL;
4918 } else if (unlikely(!ALLOC_BIG_CHECK_SIZE(power, base->size + 1))) {
4919 FREE_BIG(square, base->size + 1);
4920 raise_error(MEMORY_ERROR);
4921 } else {
4922 if (IS_NEGATIVE(base->bigdigits[base->size - 1])) {
4923 negative = TRUE;
4924 positive_copy_of_negative_big(square, base);
4925 } else {
4926 square->size = base->size;
4927 memcpy(square->bigdigits, base->bigdigits,
4928 (size_t) base->size * sizeof(bigDigitType));
4929 } /* if */
4930 if (exponent & 1) {
4931 power->size = square->size;
4932 memcpy(power->bigdigits, square->bigdigits,
4933 (size_t) square->size * sizeof(bigDigitType));
4934 } else {
4935 negative = FALSE;
4936 power->size = 1;
4937 power->bigdigits[0] = 1;
4938 } /* if */
4939 exponent >>= 1;
4940 while (exponent != 0 && square != NULL && power != NULL) {
4941 big_help = square;
4942 square = uBigSquareK(square);
4943 FREE_BIG(big_help, big_help->size);
4944 if (square != NULL) {
4945 if (exponent & 1) {
4946 big_help = power;
4947 power = uBigMultK(power, square, FALSE);
4948 FREE_BIG(big_help, big_help->size);
4949 } /* if */
4950 exponent >>= 1;
4951 } /* if */
4952 } /* while */
4953 if (unlikely(square == NULL)) {
4954 if (power != NULL) {
4955 FREE_BIG(power, power->size);
4956 } /* if */
4957 raise_error(MEMORY_ERROR);
4958 power = NULL;
4959 } else {
4960 FREE_BIG(square, square->size);
4961 if (unlikely(power == NULL)) {
4962 raise_error(MEMORY_ERROR);
4963 } else {
4964 if (negative) {
4965 negate_positive_big(power);
4966 } /* if */
4967 power = normalize(power);
4968 } /* if */
4969 } /* if */
4970 } /* if */
4971 logFunction(printf("bigIPow --> %s (size=" FMT_U_MEM ")\n",
4972 bigHexCStri(power), power != NULL ? power->size : 0););
4973 return power;
4974 } /* bigIPow */
4975
4976
4977
4978 /**
4979 * Compute the exponentiation of a bigdigit base with an integer exponent.
4980 * @param base Base that must be in the range of signedBigDigitType.
4981 * @return the result of the exponentiation.
4982 * @exception NUMERIC_ERROR If the exponent is negative.
4983 */
bigIPowSignedDigit(intType base,intType exponent)4984 bigIntType bigIPowSignedDigit (intType base, intType exponent)
4985
4986 {
4987 bigIntType power;
4988
4989 /* bigIPowSignedDigit */
4990 logFunction(printf("bigIPowSignedDigit(" FMT_D ", " FMT_D ")\n",
4991 base, exponent););
4992 if (exponent <= 1) {
4993 if (unlikely(exponent < 0)) {
4994 logError(printf("bigIPowSignedDigit(" FMT_D ", " FMT_D "): "
4995 "Exponent is negative.\n",
4996 base, exponent););
4997 raise_error(NUMERIC_ERROR);
4998 power = NULL;
4999 } else {
5000 if (unlikely(!ALLOC_BIG_SIZE_OK(power, 1))) {
5001 raise_error(MEMORY_ERROR);
5002 } else {
5003 power->size = 1;
5004 power->bigdigits[0] = exponent == 1 ? (bigDigitType) base : 1;
5005 } /* if */
5006 } /* if */
5007 } else {
5008 power = bigIPow1((bigDigitType) base, exponent);
5009 } /* if */
5010 logFunction(printf("bigIPowSignedDigit --> %s (size=" FMT_U_MEM ")\n",
5011 bigHexCStri(power), power != NULL ? power->size : 0););
5012 return power;
5013 } /* bigIPowSignedDigit */
5014
5015
5016
5017 /**
5018 * Compute the truncated base 10 logarithm of a 'bigInteger' number.
5019 * The definition of 'log10' is extended by defining log10(0) = -1_.
5020 * @return the truncated base 10 logarithm.
5021 * @exception NUMERIC_ERROR The number is negative.
5022 */
bigLog10(const const_bigIntType big1)5023 bigIntType bigLog10 (const const_bigIntType big1)
5024
5025 {
5026 bigIntType unsigned_big;
5027 bigIntType powerOf10;
5028 bigDigitType digit;
5029 memSizeType largeDecimalBlockCount;
5030 memSizeType decimalBlockCount;
5031 bigIntType logarithm;
5032
5033 /* bigLog10 */
5034 logFunction(printf("bigLog10(%s)\n", bigHexCStri(big1)););
5035 if (unlikely(IS_NEGATIVE(big1->bigdigits[big1->size - 1]))) {
5036 logError(printf("bigLog10(%s): Number is negative.\n",
5037 bigHexCStri(big1)););
5038 raise_error(NUMERIC_ERROR);
5039 logarithm = NULL;
5040 } else if (big1->size == 1 && big1->bigdigits[0] == 0) {
5041 if (unlikely(!ALLOC_BIG_SIZE_OK(logarithm, 1))) {
5042 raise_error(MEMORY_ERROR);
5043 } else {
5044 logarithm->size = 1;
5045 logarithm->bigdigits[0] = BIGDIGIT_MASK;
5046 } /* if */
5047 } else {
5048 if (unlikely(!ALLOC_BIG_SIZE_OK(unsigned_big, big1->size))) {
5049 raise_error(MEMORY_ERROR);
5050 logarithm = NULL;
5051 } else {
5052 unsigned_big->size = big1->size;
5053 memcpy(unsigned_big->bigdigits, big1->bigdigits,
5054 (size_t) big1->size * sizeof(bigDigitType));
5055 decimalBlockCount = 0;
5056 if (unsigned_big->size > 2) {
5057 if (unsigned_big->size - 1 <= MAX_MEM_INDEX) {
5058 decimalBlockCount = unsigned_big->size - 1;
5059 } else {
5060 decimalBlockCount = MAX_MEM_INDEX;
5061 } /* if */
5062 powerOf10 = bigIPow1(POWER_OF_10_IN_BIGDIGIT, (intType) (decimalBlockCount));
5063 unsigned_big = bigMDiv(unsigned_big, powerOf10);
5064 bigDestr(powerOf10);
5065 } /* if */
5066 largeDecimalBlockCount = 0;
5067 while (unsigned_big->size > 2) {
5068 uBigRShift(unsigned_big, QUINARY_DIGITS_IN_BIGDIGIT);
5069 if (unsigned_big->bigdigits[unsigned_big->size - 1] == 0) {
5070 unsigned_big->size--;
5071 } /* if */
5072 uBigDivideByPowerOf5(unsigned_big);
5073 if (unsigned_big->bigdigits[unsigned_big->size - 1] == 0) {
5074 unsigned_big->size--;
5075 } /* if */
5076 largeDecimalBlockCount++;
5077 } /* while */
5078 while (unsigned_big->size > 1 ||
5079 unsigned_big->bigdigits[0] >= POWER_OF_10_IN_BIGDIGIT) {
5080 (void) uBigDivideByPowerOf10(unsigned_big);
5081 /* printf("unsigned_big->size=" FMT_U_MEM ", digit=" FMT_U_DIG "\n",
5082 unsigned_big->size, digit); */
5083 if (unsigned_big->bigdigits[unsigned_big->size - 1] == 0) {
5084 unsigned_big->size--;
5085 } /* if */
5086 decimalBlockCount++;
5087 } /* while */
5088 digit = unsigned_big->bigdigits[0];
5089 FREE_BIG(unsigned_big, big1->size + 1);
5090 #if POINTER_SIZE == 32
5091 logarithm = bigFromUInt32(decimalBlockCount);
5092 #elif POINTER_SIZE == 64
5093 logarithm = bigFromUInt64(decimalBlockCount);
5094 #endif
5095 if (logarithm != NULL) {
5096 bigMultAssign1(&logarithm, DECIMAL_DIGITS_IN_BIGDIGIT);
5097 #if BIGDIGIT_SIZE < 32
5098 {
5099 bigIntType numDigits = bigFromUInt32(
5100 largeDecimalBlockCount * QUINARY_DIGITS_IN_BIGDIGIT);
5101 bigAddAssign(&logarithm, numDigits);
5102 bigDestr(numDigits);
5103 }
5104 #else
5105 bigAddAssignSignedDigit(&logarithm,
5106 (intType) (largeDecimalBlockCount * QUINARY_DIGITS_IN_BIGDIGIT));
5107 #endif
5108 /* printf("digit: " FMT_U_DIG "\n", digit); */
5109 digit /= 10;
5110 while (digit != 0) {
5111 bigIncr(&logarithm);
5112 digit /= 10;
5113 } /* while */
5114 } /* if */
5115 } /* if */
5116 } /* if */
5117 logFunction(printf("bigLog10 --> %s\n", bigHexCStri(logarithm)););
5118 return logarithm;
5119 } /* bigLog10 */
5120
5121
5122
5123 /**
5124 * Compute the truncated base 2 logarithm of a 'bigInteger' number.
5125 * The definition of 'log2' is extended by defining log2(0) = -1_.
5126 * @return the truncated base 2 logarithm.
5127 * @exception NUMERIC_ERROR The number is negative.
5128 */
bigLog2(const const_bigIntType big1)5129 bigIntType bigLog2 (const const_bigIntType big1)
5130
5131 {
5132 memSizeType number;
5133 memSizeType pos;
5134 intType bigdigit_log2;
5135 memSizeType logarithm_size;
5136 bigIntType logarithm;
5137
5138 /* bigLog2 */
5139 logFunction(printf("bigLog2(%s)\n", bigHexCStri(big1)););
5140 if (unlikely(IS_NEGATIVE(big1->bigdigits[big1->size - 1]))) {
5141 logError(printf("bigLog2(%s): Number is negative.\n",
5142 bigHexCStri(big1)););
5143 raise_error(NUMERIC_ERROR);
5144 logarithm = NULL;
5145 } else {
5146 /* The logarithm_size is incremented by one to take the space */
5147 /* needed for the shift by BIGDIGIT_LOG2_SIZE into account. */
5148 logarithm_size = sizeof(memSizeType) / (BIGDIGIT_SIZE >> 3) + 1;
5149 if (unlikely(!ALLOC_BIG_SIZE_OK(logarithm, logarithm_size))) {
5150 raise_error(MEMORY_ERROR);
5151 } else {
5152 logarithm->size = logarithm_size;
5153 number = big1->size - 1;
5154 logarithm->bigdigits[0] = (bigDigitType) (number & BIGDIGIT_MASK);
5155 for (pos = 1; pos < logarithm_size; pos++) {
5156 /* POINTER_SIZE is equal to sizeof(memSizeType) << 3 */
5157 #if POINTER_SIZE > BIGDIGIT_SIZE
5158 /* The number does not fit into one bigdigit */
5159 number >>= BIGDIGIT_SIZE;
5160 logarithm->bigdigits[pos] = (bigDigitType) (number & BIGDIGIT_MASK);
5161 #else
5162 /* The number fits into one bigdigit */
5163 logarithm->bigdigits[pos] = 0;
5164 #endif
5165 } /* for */
5166 uBigLShift(logarithm, BIGDIGIT_LOG2_SIZE);
5167 bigdigit_log2 = digitMostSignificantBit(big1->bigdigits[big1->size - 1]);
5168 if (bigdigit_log2 == -1) {
5169 uBigDecr(logarithm);
5170 } else {
5171 logarithm->bigdigits[0] |= (bigDigitType) bigdigit_log2;
5172 } /* if */
5173 logarithm = normalize(logarithm);
5174 } /* if */
5175 } /* if */
5176 logFunction(printf("bigLog2 --> %s\n", bigHexCStri(logarithm)););
5177 return logarithm;
5178 } /* bigLog2 */
5179
5180
5181
5182 /**
5183 * Create a number from the lower bits of big1.
5184 * This corresponds to the modulo if the dividend is a power of two:
5185 * bigLowerBits(big1, bits) corresponds to big1 mod (2_ ** bits)
5186 * @param bits Number of lower bits to select from big1.
5187 * @return a number in the range 0 .. pred(2_ ** bits).
5188 * @exception NUMERIC_ERROR The number of bits is negative.
5189 */
bigLowerBits(const const_bigIntType big1,const intType bits)5190 bigIntType bigLowerBits (const const_bigIntType big1, const intType bits)
5191
5192 {
5193 memSizeType big1_size;
5194 memSizeType pos;
5195 int bit_pos;
5196 boolType add_sign_digit = FALSE;
5197 bigDigitType digit_mask;
5198 memSizeType idx;
5199 memSizeType result_size;
5200 bigIntType result;
5201
5202 /* bigLowerBits */
5203 logFunction(printf("bigLowerBits(%s, " FMT_D ")\n",
5204 bigHexCStri(big1), bits););
5205 if (unlikely(bits <= 0)) {
5206 if (unlikely(bits != 0)) {
5207 logError(printf("bigLowerBits(%s, " FMT_D "): "
5208 "Number of bits is negative.\n",
5209 bigHexCStri(big1), bits););
5210 raise_error(NUMERIC_ERROR);
5211 result = NULL;
5212 } else {
5213 if (unlikely(!ALLOC_BIG_SIZE_OK(result, 1))) {
5214 raise_error(MEMORY_ERROR);
5215 } else {
5216 result->size = 1;
5217 result->bigdigits[0] = (bigDigitType) 0;
5218 } /* if */
5219 } /* if */
5220 } else {
5221 big1_size = big1->size;
5222 pos = (memSizeType) (bits - 1) >> BIGDIGIT_LOG2_SIZE;
5223 if (pos >= big1_size) {
5224 if (IS_NEGATIVE(big1->bigdigits[big1_size - 1])) {
5225 result_size = pos + 1;
5226 bit_pos = (int) ((bits - 1) & BIGDIGIT_SIZE_MASK);
5227 digit_mask = BIGDIGIT_MASK >> (BIGDIGIT_SIZE - bit_pos - 1);
5228 if (bit_pos == BIGDIGIT_SIZE_MASK) {
5229 add_sign_digit = TRUE;
5230 result_size++;
5231 } /* if */
5232 } else {
5233 result_size = big1_size;
5234 digit_mask = BIGDIGIT_MASK;
5235 } /* if */
5236 } else {
5237 result_size = pos + 1;
5238 bit_pos = (int) ((bits - 1) & BIGDIGIT_SIZE_MASK);
5239 digit_mask = BIGDIGIT_MASK >> (BIGDIGIT_SIZE - bit_pos - 1);
5240 if (bit_pos == BIGDIGIT_SIZE_MASK && IS_NEGATIVE(big1->bigdigits[pos])) {
5241 add_sign_digit = TRUE;
5242 result_size++;
5243 } /* if */
5244 } /* if */
5245 if (unlikely(!ALLOC_BIG_CHECK_SIZE(result, result_size))) {
5246 raise_error(MEMORY_ERROR);
5247 } else {
5248 result->size = result_size;
5249 idx = result_size - 1;
5250 if (add_sign_digit) {
5251 result->bigdigits[idx] = (bigDigitType) 0;
5252 idx--;
5253 } /* if */
5254 if (idx >= big1_size) {
5255 result->bigdigits[idx] = digit_mask;
5256 while (idx > big1_size) {
5257 idx--;
5258 result->bigdigits[idx] = BIGDIGIT_MASK;
5259 } /* while */
5260 } else {
5261 /* printf("mask = " F_X_DIG(08) "\n", digit_mask); */
5262 result->bigdigits[idx] = big1->bigdigits[idx] & digit_mask;
5263 } /* if */
5264 memcpy(result->bigdigits, big1->bigdigits,
5265 (size_t) idx * sizeof(bigDigitType));
5266 } /* if */
5267 } /* if */
5268 result = normalize(result);
5269 logFunction(printf("bigLowerBits --> %s (size=" FMT_U_MEM ")\n",
5270 bigHexCStri(result), result->size););
5271 return result;
5272 } /* bigLowerBits */
5273
5274
5275
5276 /**
5277 * Create a number from the lower bits of big1.
5278 * Big1 is assumed to be a temporary value which is reused.
5279 * This corresponds to the modulo if the dividend is a power of two:
5280 * bigLowerBits(big1, bits) corresponds to big1 mod (2_ ** bits)
5281 * @param bits Number of lower bits to select from big1.
5282 * @return a number in the range 0 .. pred(2_ ** bits).
5283 * @exception NUMERIC_ERROR The number of bits is negative.
5284 */
bigLowerBitsTemp(const bigIntType big1,const intType bits)5285 bigIntType bigLowerBitsTemp (const bigIntType big1, const intType bits)
5286
5287 {
5288 memSizeType big1_size;
5289 memSizeType pos;
5290 int bit_pos;
5291 boolType add_sign_digit = FALSE;
5292 bigDigitType digit_mask;
5293 memSizeType idx;
5294 memSizeType result_size;
5295 bigIntType result;
5296
5297 /* bigLowerBitsTemp */
5298 logFunction(printf("bigLowerBitsTemp(%s, " FMT_D ")\n",
5299 bigHexCStri(big1), bits););
5300 big1_size = big1->size;
5301 if (unlikely(bits <= 0)) {
5302 FREE_BIG(big1, big1_size);
5303 if (unlikely(bits != 0)) {
5304 logError(printf("bigLowerBitsTemp(%s, " FMT_D "): "
5305 "Number of bits is negative.\n",
5306 bigHexCStri(big1), bits););
5307 raise_error(NUMERIC_ERROR);
5308 result = NULL;
5309 } else {
5310 if (unlikely(!ALLOC_BIG_SIZE_OK(result, 1))) {
5311 raise_error(MEMORY_ERROR);
5312 } else {
5313 result->size = 1;
5314 result->bigdigits[0] = (bigDigitType) 0;
5315 } /* if */
5316 } /* if */
5317 } else {
5318 pos = (memSizeType) (bits - 1) >> BIGDIGIT_LOG2_SIZE;
5319 if (pos >= big1_size) {
5320 if (IS_NEGATIVE(big1->bigdigits[big1_size - 1])) {
5321 result_size = pos + 1;
5322 bit_pos = (int) ((bits - 1) & BIGDIGIT_SIZE_MASK);
5323 digit_mask = BIGDIGIT_MASK >> (BIGDIGIT_SIZE - bit_pos - 1);
5324 if (bit_pos == BIGDIGIT_SIZE_MASK) {
5325 add_sign_digit = TRUE;
5326 result_size++;
5327 } /* if */
5328 } else {
5329 result_size = big1_size;
5330 digit_mask = BIGDIGIT_MASK;
5331 } /* if */
5332 } else {
5333 result_size = pos + 1;
5334 bit_pos = (int) ((bits - 1) & BIGDIGIT_SIZE_MASK);
5335 digit_mask = BIGDIGIT_MASK >> (BIGDIGIT_SIZE - bit_pos - 1);
5336 if (bit_pos == BIGDIGIT_SIZE_MASK && IS_NEGATIVE(big1->bigdigits[pos])) {
5337 add_sign_digit = TRUE;
5338 result_size++;
5339 } /* if */
5340 } /* if */
5341 if (big1_size != result_size) {
5342 REALLOC_BIG_CHECK_SIZE(result, big1, big1_size, result_size);
5343 } else {
5344 result = big1;
5345 } /* if */
5346 if (unlikely(result == NULL)) {
5347 FREE_BIG(big1, big1_size);
5348 raise_error(MEMORY_ERROR);
5349 } else {
5350 COUNT3_BIG(big1_size, result_size);
5351 result->size = result_size;
5352 idx = result_size - 1;
5353 if (add_sign_digit) {
5354 result->bigdigits[idx] = (bigDigitType) 0;
5355 idx--;
5356 } /* if */
5357 if (idx >= big1_size) {
5358 result->bigdigits[idx] = digit_mask;
5359 while (idx > big1_size) {
5360 idx--;
5361 result->bigdigits[idx] = BIGDIGIT_MASK;
5362 } /* while */
5363 } else {
5364 /* printf("mask = " F_X_DIG(08) "\n", digit_mask); */
5365 result->bigdigits[idx] = result->bigdigits[idx] & digit_mask;
5366 } /* if */
5367 } /* if */
5368 } /* if */
5369 result = normalize(result);
5370 logFunction(printf("bigLowerBitsTemp --> %s (size=" FMT_U_MEM ")\n",
5371 bigHexCStri(result), result->size););
5372 return result;
5373 } /* bigLowerBitsTemp */
5374
5375
5376
bigLowerBits64(const const_bigIntType big1)5377 uint64Type bigLowerBits64 (const const_bigIntType big1)
5378
5379 {
5380 memSizeType pos;
5381 uint64Type result;
5382
5383 /* bigLowerBits64 */
5384 logFunction(printf("bigLowerBits64(%s)\n", bigHexCStri(big1)););
5385 pos = big1->size - 1;
5386 if (pos >= sizeof(uint64Type) / (BIGDIGIT_SIZE >> 3)) {
5387 pos = sizeof(uint64Type) / (BIGDIGIT_SIZE >> 3) - 1;
5388 } /* if */
5389 result = (uint64Type) big1->bigdigits[pos];
5390 #if BIGDIGIT_SIZE < 64
5391 while (pos > 0) {
5392 pos--;
5393 result <<= BIGDIGIT_SIZE;
5394 result |= (uint64Type) big1->bigdigits[pos];
5395 } /* while */
5396 #endif
5397 logFunction(printf("bigLowerBits64(%s) --> " FMT_U64 "\n",
5398 bigHexCStri(big1), result););
5399 return result;
5400 } /* bigLowerBits64 */
5401
5402
5403
5404 /**
5405 * Index of the lowest-order one bit.
5406 * For A <> 0 this is equal to the number of lowest-order zero bits.
5407 * @return the number of lowest-order zero bits or -1 for lowestSetBit(0).
5408 * @exception RANGE_ERROR The result does not fit into an integer.
5409 */
bigLowestSetBit(const const_bigIntType big1)5410 intType bigLowestSetBit (const const_bigIntType big1)
5411
5412 {
5413 memSizeType big1_size;
5414 memSizeType pos = 0;
5415 intType result;
5416
5417 /* bigLowestSetBit */
5418 logFunction(printf("bigLowestSetBit(%s)\n", bigHexCStri(big1)););
5419 big1_size = big1->size;
5420 while (pos < big1_size && big1->bigdigits[pos] == 0) {
5421 pos++;
5422 } /* while */
5423 if (pos < big1_size) {
5424 result = digitLeastSignificantBit(big1->bigdigits[pos]);
5425 if (unlikely(pos > (memSizeType) (MAX_MEM_INDEX - result) >> BIGDIGIT_LOG2_SIZE)) {
5426 logError(printf("bigLowestSetBit(%s): "
5427 "Result does not fit into an integer.\n",
5428 bigHexCStri(big1)););
5429 raise_error(RANGE_ERROR);
5430 result = 0;
5431 } else {
5432 result += (intType) (pos << BIGDIGIT_LOG2_SIZE);
5433 } /* if */
5434 } else {
5435 result = -1;
5436 } /* if */
5437 logFunction(printf("bigLowestSetBit --> " FMT_D "\n", result););
5438 return result;
5439 } /* bigLowestSetBit */
5440
5441
5442
5443 /**
5444 * Shift a 'bigInteger' number left by lshift bits.
5445 * If lshift is negative a right shift is done instead.
5446 * A << B is equivalent to A * 2_ ** B if B >= 0 holds.
5447 * A << B is equivalent to A mdiv 2_ ** -B if B < 0 holds.
5448 * @return the left shifted number.
5449 * @exception MEMORY_ERROR Not enough memory to represent the result.
5450 */
bigLShift(const const_bigIntType big1,const intType lshift)5451 bigIntType bigLShift (const const_bigIntType big1, const intType lshift)
5452
5453 {
5454 unsigned int digit_rshift;
5455 unsigned int digit_lshift;
5456 bigDigitType digit_mask;
5457 bigDigitType low_digit;
5458 bigDigitType high_digit;
5459 const bigDigitType *source_digits;
5460 bigDigitType *dest_digits;
5461 memSizeType size_reduction;
5462 memSizeType pos;
5463 memSizeType result_size;
5464 bigIntType result;
5465
5466 /* bigLShift */
5467 logFunction(printf("bigLShift(%s, " FMT_D ")\n",
5468 bigHexCStri(big1), lshift););
5469 if (unlikely(lshift < 0)) {
5470 if (unlikely(TWOS_COMPLEMENT_INTTYPE && lshift == INTTYPE_MIN)) {
5471 result = bigRShift(big1, INTTYPE_MAX);
5472 if (result != NULL) {
5473 bigRShiftAssign(&result, 1);
5474 } /* if */
5475 } else {
5476 result = bigRShift(big1, -lshift);
5477 } /* if */
5478 } else if (unlikely(big1->size == 1 && big1->bigdigits[0] == 0)) {
5479 if (unlikely(!ALLOC_BIG_SIZE_OK(result, 1))) {
5480 raise_error(MEMORY_ERROR);
5481 } else {
5482 result->size = 1;
5483 result->bigdigits[0] = 0;
5484 } /* if */
5485 } else if ((lshift & BIGDIGIT_SIZE_MASK) == 0) {
5486 if (unlikely((uintType) lshift >> BIGDIGIT_LOG2_SIZE > MAX_BIG_LEN - big1->size)) {
5487 raise_error(MEMORY_ERROR);
5488 result = NULL;
5489 } else {
5490 result_size = big1->size + (memSizeType) ((uintType) lshift >> BIGDIGIT_LOG2_SIZE);
5491 if (unlikely(!ALLOC_BIG_SIZE_OK(result, result_size))) {
5492 raise_error(MEMORY_ERROR);
5493 } else {
5494 result->size = result_size;
5495 memcpy(&result->bigdigits[lshift >> BIGDIGIT_LOG2_SIZE], big1->bigdigits,
5496 (size_t) big1->size * sizeof(bigDigitType));
5497 memset(result->bigdigits, 0,
5498 (memSizeType) ((uintType) lshift >> BIGDIGIT_LOG2_SIZE) * sizeof(bigDigitType));
5499 } /* if */
5500 } /* if */
5501 } else if (unlikely(((uintType) lshift >> BIGDIGIT_LOG2_SIZE) + 1 > MAX_BIG_LEN - big1->size)) {
5502 raise_error(MEMORY_ERROR);
5503 result = NULL;
5504 } else {
5505 result_size = big1->size + (memSizeType) ((uintType) lshift >> BIGDIGIT_LOG2_SIZE) + 1;
5506 digit_lshift = (unsigned int) ((uintType) lshift & BIGDIGIT_SIZE_MASK);
5507 digit_rshift = BIGDIGIT_SIZE - digit_lshift;
5508 size_reduction = 0;
5509 low_digit = big1->bigdigits[big1->size - 1];
5510 if (IS_NEGATIVE(low_digit)) {
5511 digit_mask = (BIGDIGIT_MASK << (digit_rshift - 1)) & BIGDIGIT_MASK;
5512 if ((low_digit & digit_mask) == digit_mask) {
5513 result_size--;
5514 size_reduction = 1;
5515 } else {
5516 low_digit = BIGDIGIT_MASK;
5517 } /* if */
5518 } else {
5519 if (low_digit >> (digit_rshift - 1) == 0) {
5520 result_size--;
5521 size_reduction = 1;
5522 } else {
5523 low_digit = 0;
5524 } /* if */
5525 } /* if */
5526 if (unlikely(!ALLOC_BIG_SIZE_OK(result, result_size))) {
5527 raise_error(MEMORY_ERROR);
5528 } else {
5529 result->size = result_size;
5530 dest_digits = &result->bigdigits[result_size];
5531 if (size_reduction) {
5532 source_digits = &big1->bigdigits[big1->size - 1];
5533 } else {
5534 source_digits = &big1->bigdigits[big1->size];
5535 } /* if */
5536 high_digit = (low_digit << digit_lshift) & BIGDIGIT_MASK;
5537 for (pos = big1->size - size_reduction; pos != 0; pos--) {
5538 low_digit = *--source_digits;
5539 *--dest_digits = high_digit | (low_digit >> digit_rshift);
5540 high_digit = (low_digit << digit_lshift) & BIGDIGIT_MASK;
5541 } /* for */
5542 *--dest_digits = high_digit;
5543 if (dest_digits > result->bigdigits) {
5544 memset(result->bigdigits, 0,
5545 (memSizeType) (dest_digits - result->bigdigits) * sizeof(bigDigitType));
5546 } /* if */
5547 } /* if */
5548 } /* if */
5549 logFunction(printf("bigLShift --> %s\n", bigHexCStri(result)););
5550 return result;
5551 } /* bigLShift */
5552
5553
5554
5555 /**
5556 * Shift a number left by lshift bits and assign the result back to number.
5557 * If lshift is negative a right shift is done instead.
5558 * @exception MEMORY_ERROR Not enough memory to represent the new value.
5559 */
bigLShiftAssign(bigIntType * const big_variable,intType lshift)5560 void bigLShiftAssign (bigIntType *const big_variable, intType lshift)
5561
5562 {
5563 bigIntType big1;
5564 unsigned int digit_rshift;
5565 unsigned int digit_lshift;
5566 bigDigitType digit_mask;
5567 bigDigitType low_digit;
5568 bigDigitType high_digit;
5569 const bigDigitType *source_digits;
5570 bigDigitType *dest_digits;
5571 memSizeType size_reduction;
5572 memSizeType pos;
5573 memSizeType result_size;
5574 bigIntType result;
5575
5576 /* bigLShiftAssign */
5577 logFunction(printf("bigLShiftAssign(%s, " FMT_D ")\n",
5578 bigHexCStri(*big_variable), lshift););
5579 if (unlikely(lshift < 0)) {
5580 if (unlikely(TWOS_COMPLEMENT_INTTYPE && lshift == INTTYPE_MIN)) {
5581 bigRShiftAssign(big_variable, INTTYPE_MAX);
5582 bigRShiftAssign(big_variable, 1);
5583 } else {
5584 bigRShiftAssign(big_variable, -lshift);
5585 } /* if */
5586 } else if (likely(lshift != 0)) {
5587 big1 = *big_variable;
5588 if (big1->size == 1 && big1->bigdigits[0] == 0) {
5589 if (unlikely(!ALLOC_BIG_SIZE_OK(result, 1))) {
5590 raise_error(MEMORY_ERROR);
5591 } else {
5592 result->size = 1;
5593 result->bigdigits[0] = 0;
5594 *big_variable = result;
5595 FREE_BIG(big1, big1->size);
5596 } /* if */
5597 } else if ((lshift & BIGDIGIT_SIZE_MASK) == 0) {
5598 if (unlikely((uintType) lshift >> BIGDIGIT_LOG2_SIZE > MAX_BIG_LEN - big1->size)) {
5599 raise_error(MEMORY_ERROR);
5600 } else {
5601 result_size = big1->size + (memSizeType) ((uintType) lshift >> BIGDIGIT_LOG2_SIZE);
5602 if (unlikely(!ALLOC_BIG_SIZE_OK(result, result_size))) {
5603 raise_error(MEMORY_ERROR);
5604 } else {
5605 result->size = result_size;
5606 memcpy(&result->bigdigits[lshift >> BIGDIGIT_LOG2_SIZE], big1->bigdigits,
5607 (size_t) big1->size * sizeof(bigDigitType));
5608 memset(result->bigdigits, 0,
5609 (memSizeType) ((uintType) lshift >> BIGDIGIT_LOG2_SIZE) * sizeof(bigDigitType));
5610 *big_variable = result;
5611 FREE_BIG(big1, big1->size);
5612 } /* if */
5613 } /* if */
5614 } else if (unlikely(((uintType) lshift >> BIGDIGIT_LOG2_SIZE) + 1 > MAX_BIG_LEN - big1->size)) {
5615 raise_error(MEMORY_ERROR);
5616 } else {
5617 result_size = big1->size + (memSizeType) ((uintType) lshift >> BIGDIGIT_LOG2_SIZE) + 1;
5618 digit_lshift = (unsigned int) ((uintType) lshift & BIGDIGIT_SIZE_MASK);
5619 digit_rshift = BIGDIGIT_SIZE - digit_lshift;
5620 size_reduction = 0;
5621 low_digit = big1->bigdigits[big1->size - 1];
5622 if (IS_NEGATIVE(low_digit)) {
5623 digit_mask = (BIGDIGIT_MASK << (digit_rshift - 1)) & BIGDIGIT_MASK;
5624 if ((low_digit & digit_mask) == digit_mask) {
5625 result_size--;
5626 size_reduction = 1;
5627 } else {
5628 low_digit = BIGDIGIT_MASK;
5629 } /* if */
5630 } else {
5631 if (low_digit >> (digit_rshift - 1) == 0) {
5632 result_size--;
5633 size_reduction = 1;
5634 } else {
5635 low_digit = 0;
5636 } /* if */
5637 } /* if */
5638 if (result_size != big1->size) {
5639 if (unlikely(!ALLOC_BIG_SIZE_OK(result, result_size))) {
5640 raise_error(MEMORY_ERROR);
5641 } /* if */
5642 } else {
5643 result = big1;
5644 } /* if */
5645 if (result != NULL) {
5646 result->size = result_size;
5647 dest_digits = &result->bigdigits[result_size];
5648 if (size_reduction) {
5649 source_digits = &big1->bigdigits[big1->size - 1];
5650 } else {
5651 source_digits = &big1->bigdigits[big1->size];
5652 } /* if */
5653 high_digit = (low_digit << digit_lshift) & BIGDIGIT_MASK;
5654 for (pos = big1->size - size_reduction; pos != 0; pos--) {
5655 low_digit = *--source_digits;
5656 *--dest_digits = high_digit | (low_digit >> digit_rshift);
5657 high_digit = (low_digit << digit_lshift) & BIGDIGIT_MASK;
5658 } /* for */
5659 *--dest_digits = high_digit;
5660 if (dest_digits > result->bigdigits) {
5661 memset(result->bigdigits, 0,
5662 (memSizeType) (dest_digits - result->bigdigits) * sizeof(bigDigitType));
5663 } /* if */
5664 if (result != big1) {
5665 *big_variable = result;
5666 FREE_BIG(big1, big1->size);
5667 } /* if */
5668 } /* if */
5669 } /* if */
5670 } /* if */
5671 logFunction(printf("bigLShiftAssign --> %s\n", bigHexCStri(*big_variable)););
5672 } /* bigLShiftAssign */
5673
5674
5675
5676 /**
5677 * Shift one left by 'lshift' bits.
5678 * If 'lshift' is positive or zero this corresponds to
5679 * the computation of a power of two:
5680 * bigLShiftOne(lshift) corresponds to 2_ ** lshift
5681 * If 'lshift' is negative the result is zero.
5682 * @return one shifted left by 'lshift'.
5683 * @exception MEMORY_ERROR Not enough memory to represent the result.
5684 */
bigLShiftOne(const intType lshift)5685 bigIntType bigLShiftOne (const intType lshift)
5686
5687 {
5688 memSizeType result_size;
5689 int bit_pos;
5690 bigIntType result;
5691
5692 /* bigLShiftOne */
5693 logFunction(printf("bigLShiftOne(" FMT_D ")\n", lshift););
5694 if (unlikely(lshift < 0)) {
5695 if (unlikely(!ALLOC_BIG_SIZE_OK(result, 1))) {
5696 raise_error(MEMORY_ERROR);
5697 } else {
5698 result->size = 1;
5699 result->bigdigits[0] = 0;
5700 } /* if */
5701 } else if (unlikely((((uintType) lshift + 1) >> BIGDIGIT_LOG2_SIZE) + 1 > MAX_BIG_LEN)) {
5702 raise_error(MEMORY_ERROR);
5703 result = NULL;
5704 } else {
5705 result_size = (memSizeType) (((uintType) lshift + 1) >> BIGDIGIT_LOG2_SIZE) + 1;
5706 if (unlikely(!ALLOC_BIG_SIZE_OK(result, result_size))) {
5707 raise_error(MEMORY_ERROR);
5708 } else {
5709 result->size = result_size;
5710 bit_pos = (int) (lshift & BIGDIGIT_SIZE_MASK);
5711 if (bit_pos == BIGDIGIT_SIZE_MASK) {
5712 memset(result->bigdigits, 0, (result_size - 2) * sizeof(bigDigitType));
5713 result->bigdigits[result_size - 2] = ((bigDigitType) 1) << bit_pos;
5714 result->bigdigits[result_size - 1] = 0;
5715 } else {
5716 memset(result->bigdigits, 0, (result_size - 1) * sizeof(bigDigitType));
5717 result->bigdigits[result_size - 1] = ((bigDigitType) 1) << bit_pos;
5718 } /* if */
5719 } /* if */
5720 } /* if */
5721 logFunction(printf("bigLShiftOne --> %s\n", bigHexCStri(result)););
5722 return result;
5723 } /* bigLShiftOne */
5724
5725
5726
5727 /**
5728 * Exponentiation if the base is a power of two.
5729 * @param log2base Logarithm of the actual base ( =log2(base) )
5730 * @return (2 ** log2base) ** exponent
5731 * @exception NUMERIC_ERROR If log2base or exponent is negative.
5732 */
bigLog2BaseIPow(const intType log2base,const intType exponent)5733 bigIntType bigLog2BaseIPow (const intType log2base, const intType exponent)
5734
5735 {
5736 uintType high_shift;
5737 uintType low_shift;
5738 bigIntType power;
5739
5740 /* bigLog2BaseIPow */
5741 logFunction(printf("bigLog2BaseIPow(" FMT_D ", " FMT_D ")\n",
5742 log2base, exponent););
5743 if (unlikely(log2base < 0 || exponent < 0)) {
5744 logError(printf("bigLog2BaseIPow(" FMT_D ", " FMT_D "): "
5745 "Log2base or exponent is negative.\n",
5746 log2base, exponent););
5747 raise_error(NUMERIC_ERROR);
5748 power = NULL;
5749 } else if (likely(log2base == 1)) {
5750 power = bigLShiftOne(exponent);
5751 } else if (log2base <= 10 && exponent <= MAX_DIV_10) {
5752 power = bigLShiftOne(log2base * exponent);
5753 } else {
5754 low_shift = uintMult((uintType) log2base, (uintType) exponent, &high_shift);
5755 if (unlikely(high_shift != 0 || (intType) low_shift < 0)) {
5756 raise_error(MEMORY_ERROR);
5757 power = NULL;
5758 } else {
5759 power = bigLShiftOne((intType) low_shift);
5760 } /* if */
5761 } /* if */
5762 logFunction(printf("bigLog2BaseIPow --> %s\n", bigHexCStri(power)););
5763 return power;
5764 } /* bigLog2BaseIPow */
5765
5766
5767
5768 /**
5769 * Integer division truncated towards negative infinity.
5770 * The modulo (remainder) of this division is computed with bigMod.
5771 * Therefore this division is called modulo division (MDiv).
5772 * The memory for the result is requested and the normalized result
5773 * is returned. If divisor has just one digit or if dividend
5774 * has less digits than divisor the functions bigMDiv1() or
5775 * bigMDivSizeLess() are called. In the general case the absolute
5776 * values of dividend and divisor are taken. Then dividend is
5777 * extended by one leading zero digit. After that dividend and divisor
5778 * are shifted to the left such that the most significant bit
5779 * of divisor is set. This fulfills the preconditions for calling
5780 * uBigDiv() which does the main work of the division.
5781 * @return the quotient of the integer division.
5782 * @exception NUMERIC_ERROR If a division by zero occurs.
5783 */
bigMDiv(const const_bigIntType dividend,const const_bigIntType divisor)5784 bigIntType bigMDiv (const const_bigIntType dividend, const const_bigIntType divisor)
5785
5786 {
5787 boolType negative = FALSE;
5788 bigIntType dividend_help;
5789 bigIntType divisor_help;
5790 unsigned int shift;
5791 bigDigitType mdiv1_remainder = 0;
5792 bigIntType quotient;
5793
5794 /* bigMDiv */
5795 logFunction(printf("bigMDiv(%s,", bigHexCStri(dividend));
5796 printf("%s)\n", bigHexCStri(divisor)););
5797 if (divisor->size == 1) {
5798 quotient = bigMDiv1(dividend, divisor->bigdigits[0]);
5799 } else if (dividend->size < divisor->size) {
5800 quotient = bigMDivSizeLess(dividend, divisor);
5801 } else {
5802 if (unlikely(!ALLOC_BIG_CHECK_SIZE(dividend_help, dividend->size + 2))) {
5803 raise_error(MEMORY_ERROR);
5804 return NULL;
5805 } else {
5806 if (IS_NEGATIVE(dividend->bigdigits[dividend->size - 1])) {
5807 negative = TRUE;
5808 positive_copy_of_negative_big(dividend_help, dividend);
5809 } else {
5810 dividend_help->size = dividend->size;
5811 memcpy(dividend_help->bigdigits, dividend->bigdigits,
5812 (size_t) dividend->size * sizeof(bigDigitType));
5813 } /* if */
5814 dividend_help->bigdigits[dividend_help->size] = 0;
5815 dividend_help->size++;
5816 } /* if */
5817 if (unlikely(!ALLOC_BIG_CHECK_SIZE(divisor_help, divisor->size + 1))) {
5818 FREE_BIG(dividend_help, dividend->size + 2);
5819 raise_error(MEMORY_ERROR);
5820 return NULL;
5821 } else {
5822 if (IS_NEGATIVE(divisor->bigdigits[divisor->size - 1])) {
5823 negative = !negative;
5824 positive_copy_of_negative_big(divisor_help, divisor);
5825 } else {
5826 divisor_help->size = divisor->size;
5827 memcpy(divisor_help->bigdigits, divisor->bigdigits,
5828 (size_t) divisor->size * sizeof(bigDigitType));
5829 } /* if */
5830 } /* if */
5831 if (unlikely(!ALLOC_BIG_SIZE_OK(quotient, dividend_help->size - divisor_help->size + 1))) {
5832 FREE_BIG(dividend_help, dividend->size + 2);
5833 FREE_BIG(divisor_help, divisor->size + 1);
5834 raise_error(MEMORY_ERROR);
5835 return NULL;
5836 } else {
5837 quotient->size = dividend_help->size - divisor_help->size + 1;
5838 quotient->bigdigits[quotient->size - 1] = 0;
5839 shift = (unsigned int)
5840 (digitMostSignificantBit(divisor_help->bigdigits[divisor_help->size - 1]) + 1);
5841 if (shift == 0) {
5842 /* The most significant digit of divisor_help is 0. Just ignore it */
5843 dividend_help->size--;
5844 divisor_help->size--;
5845 if (divisor_help->size == 1) {
5846 mdiv1_remainder = uBigDivRem1(dividend_help, divisor_help->bigdigits[0], quotient);
5847 } else {
5848 uBigDiv(dividend_help, divisor_help, quotient);
5849 } /* if */
5850 } else {
5851 shift = BIGDIGIT_SIZE - shift;
5852 uBigLShift(dividend_help, shift);
5853 uBigLShift(divisor_help, shift);
5854 uBigDiv(dividend_help, divisor_help, quotient);
5855 } /* if */
5856 if (negative) {
5857 if ((divisor_help->size == 1 && mdiv1_remainder != 0) ||
5858 (divisor_help->size != 1 && uBigIsNot0(dividend_help))) {
5859 uBigIncr(quotient);
5860 } /* if */
5861 negate_positive_big(quotient);
5862 } /* if */
5863 quotient = normalize(quotient);
5864 } /* if */
5865 FREE_BIG(dividend_help, dividend->size + 2);
5866 FREE_BIG(divisor_help, divisor->size + 1);
5867 } /* if */
5868 logFunction(printf("bigMDiv --> %s\n", bigHexCStri(quotient)););
5869 return quotient;
5870 } /* bigMDiv */
5871
5872
5873
5874 /**
5875 * Compute the modulo (remainder) of the integer division bigMDiv.
5876 * The modulo has the same sign as the divisor. The memory for the result
5877 * is requested and the normalized result is returned. If divisor has
5878 * just one digit or if dividend has less digits than divisor the
5879 * functions bigMod1() or bigModSizeLess() are called. In the general case
5880 * the absolute values of dividend and divisor are taken. Then dividend is
5881 * extended by one leading zero digit. After that dividend and divisor
5882 * are shifted to the left such that the most significant bit
5883 * of divisor is set. This fulfills the preconditions for calling
5884 * uBigRem() which does the main work of the division. Afterwards
5885 * the result must be shifted to the right to get the remainder.
5886 * If dividend and divisor have the same sign the modulo has the same
5887 * value as the remainder. If the remainder is zero the modulo
5888 * is also zero. If the signs of dividend and divisor are different the
5889 * modulo is computed from the remainder by adding dividend.
5890 * @return the modulo of the integer division.
5891 * @exception NUMERIC_ERROR If a division by zero occurs.
5892 */
bigMod(const const_bigIntType dividend,const const_bigIntType divisor)5893 bigIntType bigMod (const const_bigIntType dividend, const const_bigIntType divisor)
5894
5895 {
5896 boolType negative1 = FALSE;
5897 boolType negative2 = FALSE;
5898 bigIntType divisor_help;
5899 unsigned int shift;
5900 bigIntType modulo;
5901
5902 /* bigMod */
5903 logFunction(printf("bigMod(%s,", bigHexCStri(dividend));
5904 printf("%s)\n", bigHexCStri(divisor)););
5905 if (divisor->size == 1) {
5906 modulo = bigMod1(dividend, divisor->bigdigits[0]);
5907 } else if (dividend->size < divisor->size) {
5908 modulo = bigModSizeLess(dividend, divisor);
5909 } else {
5910 if (unlikely(!ALLOC_BIG_CHECK_SIZE(modulo, dividend->size + 2))) {
5911 raise_error(MEMORY_ERROR);
5912 return NULL;
5913 } else {
5914 if (IS_NEGATIVE(dividend->bigdigits[dividend->size - 1])) {
5915 negative1 = TRUE;
5916 positive_copy_of_negative_big(modulo, dividend);
5917 } else {
5918 modulo->size = dividend->size;
5919 memcpy(modulo->bigdigits, dividend->bigdigits,
5920 (size_t) dividend->size * sizeof(bigDigitType));
5921 } /* if */
5922 modulo->bigdigits[modulo->size] = 0;
5923 modulo->size++;
5924 } /* if */
5925 if (unlikely(!ALLOC_BIG_CHECK_SIZE(divisor_help, divisor->size + 1))) {
5926 FREE_BIG(modulo, dividend->size + 2);
5927 raise_error(MEMORY_ERROR);
5928 return NULL;
5929 } else {
5930 if (IS_NEGATIVE(divisor->bigdigits[divisor->size - 1])) {
5931 negative2 = TRUE;
5932 positive_copy_of_negative_big(divisor_help, divisor);
5933 } else {
5934 divisor_help->size = divisor->size;
5935 memcpy(divisor_help->bigdigits, divisor->bigdigits,
5936 (size_t) divisor->size * sizeof(bigDigitType));
5937 } /* if */
5938 } /* if */
5939 shift = (unsigned int)
5940 (digitMostSignificantBit(divisor_help->bigdigits[divisor_help->size - 1]) + 1);
5941 if (shift == 0) {
5942 /* The most significant digit of divisor_help is 0. Just ignore it */
5943 modulo->size--;
5944 divisor_help->size--;
5945 if (divisor_help->size == 1) {
5946 modulo->bigdigits[0] = uBigRem1(modulo, divisor_help->bigdigits[0]);
5947 memset(&modulo->bigdigits[1], 0,
5948 (size_t) (modulo->size - 1) * sizeof(bigDigitType));
5949 } else {
5950 uBigRem(modulo, divisor_help);
5951 } /* if */
5952 modulo->bigdigits[modulo->size] = 0;
5953 divisor_help->size++;
5954 } else {
5955 shift = BIGDIGIT_SIZE - shift;
5956 uBigLShift(modulo, shift);
5957 uBigLShift(divisor_help, shift);
5958 uBigRem(modulo, divisor_help);
5959 uBigRShift(modulo, shift);
5960 } /* if */
5961 modulo->bigdigits[dividend->size + 1] = 0;
5962 modulo->size = dividend->size + 2;
5963 if (negative1) {
5964 if (negative2) {
5965 negate_positive_big(modulo);
5966 } else {
5967 if (uBigIsNot0(modulo)) {
5968 negate_positive_big(modulo);
5969 bigAddTo(modulo, divisor);
5970 } /* if */
5971 } /* if */
5972 } else {
5973 if (negative2) {
5974 if (uBigIsNot0(modulo)) {
5975 bigAddTo(modulo, divisor);
5976 } /* if */
5977 } /* if */
5978 } /* if */
5979 modulo = normalize(modulo);
5980 FREE_BIG(divisor_help, divisor->size + 1);
5981 } /* if */
5982 logFunction(printf("bigMod --> %s\n", bigHexCStri(modulo)););
5983 return modulo;
5984 } /* bigMod */
5985
5986
5987
5988 /**
5989 * Multiply two 'bigInteger' numbers.
5990 * @return the product of the two numbers.
5991 */
bigMult(const_bigIntType factor1,const_bigIntType factor2)5992 bigIntType bigMult (const_bigIntType factor1, const_bigIntType factor2)
5993
5994 {
5995 boolType negative = FALSE;
5996 bigIntType factor1_help = NULL;
5997 bigIntType factor2_help = NULL;
5998 bigIntType product;
5999
6000 /* bigMult */
6001 logFunction(printf("bigMult(%s,", bigHexCStri(factor1));
6002 printf("%s)\n", bigHexCStri(factor2)););
6003 if (IS_NEGATIVE(factor1->bigdigits[factor1->size - 1])) {
6004 negative = TRUE;
6005 factor1_help = alloc_positive_copy_of_negative_big(factor1);
6006 factor1 = factor1_help;
6007 if (unlikely(factor1_help == NULL)) {
6008 raise_error(MEMORY_ERROR);
6009 return NULL;
6010 } /* if */
6011 } /* if */
6012 if (IS_NEGATIVE(factor2->bigdigits[factor2->size - 1])) {
6013 negative = !negative;
6014 factor2_help = alloc_positive_copy_of_negative_big(factor2);
6015 factor2 = factor2_help;
6016 if (unlikely(factor2_help == NULL)) {
6017 if (factor1_help != NULL) {
6018 FREE_BIG(factor1_help, factor1_help->size);
6019 } /* if */
6020 raise_error(MEMORY_ERROR);
6021 return NULL;
6022 } /* if */
6023 } /* if */
6024 /* printf("bigMult(" FMT_U_MEM ", " FMT_U_MEM ")\n",
6025 factor1->size, factor2->size); */
6026 product = uBigMultK(factor1, factor2, negative);
6027 if (factor1_help != NULL) {
6028 FREE_BIG(factor1_help, factor1_help->size);
6029 } /* if */
6030 if (factor2_help != NULL) {
6031 FREE_BIG(factor2_help, factor2_help->size);
6032 } /* if */
6033 if (unlikely(product == NULL)) {
6034 raise_error(MEMORY_ERROR);
6035 } /* if */
6036 logFunction(printf("bigMult --> %s\n", bigHexCStri(product)););
6037 return product;
6038 } /* bigMult */
6039
6040
6041
6042 /**
6043 * Multiply a 'bigInteger' number by a factor and assign the result back to number.
6044 */
bigMultAssign(bigIntType * const big_variable,const_bigIntType factor)6045 void bigMultAssign (bigIntType *const big_variable, const_bigIntType factor)
6046
6047 {
6048 bigIntType product;
6049
6050 /* bigMultAssign */
6051 logFunction(printf("bigMultAssign(%s,", bigHexCStri(*big_variable));
6052 printf("%s)\n", bigHexCStri(factor)););
6053 if (factor->size == 1) {
6054 bigMultAssign1(big_variable, factor->bigdigits[0]);
6055 } else {
6056 product = bigMult(*big_variable, factor);
6057 FREE_BIG(*big_variable, (*big_variable)->size);
6058 *big_variable = product;
6059 } /* if */
6060 logFunction(printf("bigMultAssign --> %s\n", bigHexCStri(*big_variable)););
6061 } /* bigMultAssign */
6062
6063
6064
6065 /**
6066 * Multiply factor1 with the bigdigit factor2.
6067 * The range of factor2 is restricted and it is the job of the
6068 * compiler to assure that factor2 is within the allowed range.
6069 * @param factor2 Multiplication factor that must be
6070 * in the range of signedBigDigitType.
6071 * @return the product of factor1 * factor2.
6072 */
bigMultSignedDigit(const_bigIntType factor1,intType factor2)6073 bigIntType bigMultSignedDigit (const_bigIntType factor1, intType factor2)
6074
6075 {
6076 bigIntType product;
6077
6078 /* bigMultSignedDigit */
6079 logFunction(printf("bigMultSignedDigit(%s, " FMT_D ")\n",
6080 bigHexCStri(factor1), factor2););
6081 if (unlikely(!ALLOC_BIG_CHECK_SIZE(product, factor1->size + 1))) {
6082 raise_error(MEMORY_ERROR);
6083 } else {
6084 product->size = factor1->size + 1;
6085 if (factor2 < 0) {
6086 if (IS_NEGATIVE(factor1->bigdigits[factor1->size - 1])) {
6087 uBigMultNegativeWithNegatedDigit(factor1, (bigDigitType) -factor2 & BIGDIGIT_MASK, product);
6088 } else {
6089 uBigMultPositiveWithNegatedDigit(factor1, (bigDigitType) -factor2 & BIGDIGIT_MASK, product);
6090 } /* if */
6091 } else {
6092 if (IS_NEGATIVE(factor1->bigdigits[factor1->size - 1])) {
6093 uBigMultNegativeWithDigit(factor1, (bigDigitType) factor2, product);
6094 } else {
6095 uBigMultPositiveWithDigit(factor1, (bigDigitType) factor2, product);
6096 } /* if */
6097 } /* if */
6098 product = normalize(product);
6099 } /* if */
6100 logFunction(printf("bigMultSignedDigit --> %s\n", bigHexCStri(product)););
6101 return product;
6102 } /* bigMultSignedDigit */
6103
6104
6105
6106 /**
6107 * Minus sign, negate a 'bigInteger' number.
6108 * @return the negated value of the number.
6109 * @exception MEMORY_ERROR Not enough memory to represent the result.
6110 */
bigNegate(const const_bigIntType big1)6111 bigIntType bigNegate (const const_bigIntType big1)
6112
6113 {
6114 memSizeType pos;
6115 doubleBigDigitType carry = 1;
6116 bigIntType resized_negatedValue;
6117 bigIntType negatedValue;
6118
6119 /* bigNegate */
6120 logFunction(printf("bigNegate(%s)\n", bigHexCStri(big1)););
6121 if (unlikely(!ALLOC_BIG_SIZE_OK(negatedValue, big1->size))) {
6122 raise_error(MEMORY_ERROR);
6123 } else {
6124 negatedValue->size = big1->size;
6125 pos = 0;
6126 do {
6127 carry += ~big1->bigdigits[pos] & BIGDIGIT_MASK;
6128 negatedValue->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
6129 carry >>= BIGDIGIT_SIZE;
6130 pos++;
6131 } while (pos < big1->size);
6132 if (IS_NEGATIVE(negatedValue->bigdigits[pos - 1])) {
6133 if (IS_NEGATIVE(big1->bigdigits[pos - 1])) {
6134 REALLOC_BIG_CHECK_SIZE(resized_negatedValue, negatedValue, pos, pos + 1);
6135 if (unlikely(resized_negatedValue == NULL)) {
6136 FREE_BIG(negatedValue, pos);
6137 raise_error(MEMORY_ERROR);
6138 negatedValue = NULL;
6139 } else {
6140 negatedValue = resized_negatedValue;
6141 COUNT3_BIG(pos, pos + 1);
6142 negatedValue->size++;
6143 negatedValue->bigdigits[pos] = 0;
6144 } /* if */
6145 } else if (negatedValue->bigdigits[pos - 1] == BIGDIGIT_MASK &&
6146 pos >= 2 && IS_NEGATIVE(negatedValue->bigdigits[pos - 2])) {
6147 REALLOC_BIG_SIZE_OK(resized_negatedValue, negatedValue, pos, pos - 1);
6148 /* Avoid a MEMORY_ERROR in the strange case */
6149 /* if a 'realloc' which shrinks memory fails. */
6150 if (likely(resized_negatedValue != NULL)) {
6151 negatedValue = resized_negatedValue;
6152 } /* if */
6153 COUNT3_BIG(pos, pos - 1);
6154 negatedValue->size--;
6155 } /* if */
6156 } /* if */
6157 } /* if */
6158 logFunction(printf("bigNegate --> %s\n", bigHexCStri(negatedValue)););
6159 return negatedValue;
6160 } /* bigNegate */
6161
6162
6163
6164 /**
6165 * Minus sign, negate a 'bigInteger' number.
6166 * Big1 is assumed to be a temporary value which is reused.
6167 * @return the negated value of the number.
6168 * @exception MEMORY_ERROR Not enough memory to represent the result.
6169 */
bigNegateTemp(bigIntType big1)6170 bigIntType bigNegateTemp (bigIntType big1)
6171
6172 {
6173 memSizeType pos = 0;
6174 doubleBigDigitType carry = 1;
6175 boolType negative;
6176 bigIntType resized_big1;
6177
6178 /* bigNegateTemp */
6179 logFunction(printf("bigNegateTemp(%s)\n", bigHexCStri(big1)););
6180 negative = IS_NEGATIVE(big1->bigdigits[big1->size - 1]);
6181 do {
6182 carry += ~big1->bigdigits[pos] & BIGDIGIT_MASK;
6183 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
6184 carry >>= BIGDIGIT_SIZE;
6185 pos++;
6186 } while (pos < big1->size);
6187 if (IS_NEGATIVE(big1->bigdigits[pos - 1])) {
6188 if (negative) {
6189 REALLOC_BIG_CHECK_SIZE(resized_big1, big1, pos, pos + 1);
6190 if (unlikely(resized_big1 == NULL)) {
6191 FREE_BIG(big1, pos);
6192 raise_error(MEMORY_ERROR);
6193 big1 = NULL;
6194 } else {
6195 big1 = resized_big1;
6196 COUNT3_BIG(pos, pos + 1);
6197 big1->size++;
6198 big1->bigdigits[pos] = 0;
6199 } /* if */
6200 } else if (big1->bigdigits[pos - 1] == BIGDIGIT_MASK &&
6201 pos >= 2 && IS_NEGATIVE(big1->bigdigits[pos - 2])) {
6202 REALLOC_BIG_SIZE_OK(resized_big1, big1, pos, pos - 1);
6203 /* Avoid a MEMORY_ERROR in the strange case */
6204 /* if a 'realloc' which shrinks memory fails. */
6205 if (likely(resized_big1 != NULL)) {
6206 big1 = resized_big1;
6207 } /* if */
6208 COUNT3_BIG(pos, pos - 1);
6209 big1->size--;
6210 } /* if */
6211 } /* if */
6212 logFunction(printf("bigNegateTemp --> %s\n", bigHexCStri(big1)););
6213 return big1;
6214 } /* bigNegateTemp */
6215
6216
6217
6218 /**
6219 * Determine if a 'bigInteger' number is odd.
6220 * @return TRUE if the number is odd,
6221 * FALSE otherwise.
6222 */
bigOdd(const const_bigIntType big1)6223 boolType bigOdd (const const_bigIntType big1)
6224
6225 { /* bigOdd */
6226 return (boolType) (big1->bigdigits[0] & 1);
6227 } /* bigOdd */
6228
6229
6230
bigOr(const_bigIntType big1,const_bigIntType big2)6231 bigIntType bigOr (const_bigIntType big1, const_bigIntType big2)
6232
6233 {
6234 const_bigIntType help_big;
6235 memSizeType pos;
6236 bigDigitType big2_sign;
6237 bigIntType result;
6238
6239 /* bigOr */
6240 logFunction(printf("bigOr(%s,", bigHexCStri(big1));
6241 printf("%s)\n", bigHexCStri(big2)););
6242 if (big2->size > big1->size) {
6243 help_big = big1;
6244 big1 = big2;
6245 big2 = help_big;
6246 } /* if */
6247 if (unlikely(!ALLOC_BIG_SIZE_OK(result, big1->size))) {
6248 raise_error(MEMORY_ERROR);
6249 } else {
6250 pos = 0;
6251 do {
6252 result->bigdigits[pos] = big1->bigdigits[pos] | big2->bigdigits[pos];
6253 pos++;
6254 } while (pos < big2->size);
6255 big2_sign = IS_NEGATIVE(big2->bigdigits[pos - 1]) ? BIGDIGIT_MASK : 0;
6256 for (; pos < big1->size; pos++) {
6257 result->bigdigits[pos] = big1->bigdigits[pos] | big2_sign;
6258 } /* for */
6259 result->size = pos;
6260 result = normalize(result);
6261 } /* if */
6262 logFunction(printf("bigOr --> %s\n", bigHexCStri(result)););
6263 return result;
6264 } /* bigOr */
6265
6266
6267
6268 /**
6269 * Convert a string to a 'bigInteger' number.
6270 * The string must contain an integer literal consisting of an
6271 * optional + or - sign, followed by a sequence of digits. Other
6272 * characters as well as leading or trailing whitespace characters are
6273 * not allowed. The sequence of digits is taken to be decimal.
6274 * @return the 'bigInteger' result of the conversion.
6275 * @exception RANGE_ERROR If the string is empty or does not contain
6276 * an integer literal.
6277 * @exception MEMORY_ERROR Not enough memory to represent the result.
6278 */
bigParse(const const_striType stri)6279 bigIntType bigParse (const const_striType stri)
6280
6281 {
6282 memSizeType result_size;
6283 boolType okay;
6284 boolType negative;
6285 memSizeType position = 0;
6286 memSizeType limit;
6287 bigDigitType bigDigit;
6288 bigIntType result;
6289
6290 /* bigParse */
6291 logFunction(printf("bigParse(\"%s\")\n", striAsUnquotedCStri(stri)););
6292 if (likely(stri->size != 0)) {
6293 if (stri->mem[0] == ((strElemType) '-')) {
6294 negative = TRUE;
6295 position++;
6296 } else {
6297 if (stri->mem[0] == ((strElemType) '+')) {
6298 position++;
6299 } /* if */
6300 negative = FALSE;
6301 } /* if */
6302 } /* if */
6303 if (unlikely(position >= stri->size)) {
6304 logError(printf("bigParse(\"%s\"): "
6305 "Digit missing.\n",
6306 striAsUnquotedCStri(stri)););
6307 raise_error(RANGE_ERROR);
6308 result = NULL;
6309 } else {
6310 result_size = (stri->size - 1) / DECIMAL_DIGITS_IN_BIGDIGIT + 1;
6311 if (unlikely(!ALLOC_BIG(result, result_size))) {
6312 raise_error(MEMORY_ERROR);
6313 } else {
6314 result->size = 1;
6315 result->bigdigits[0] = 0;
6316 okay = TRUE;
6317 limit = (stri->size - position - 1) % DECIMAL_DIGITS_IN_BIGDIGIT + position + 1;
6318 do {
6319 bigDigit = 0;
6320 while (position < limit && okay) {
6321 if (likely(stri->mem[position] >= ((strElemType) '0') &&
6322 stri->mem[position] <= ((strElemType) '9'))) {
6323 bigDigit = (bigDigitType) 10 * bigDigit +
6324 (bigDigitType) stri->mem[position] - (bigDigitType) '0';
6325 } else {
6326 okay = FALSE;
6327 } /* if */
6328 position++;
6329 } /* while */
6330 uBigMultByPowerOf10AndAdd(result, (doubleBigDigitType) bigDigit);
6331 limit += DECIMAL_DIGITS_IN_BIGDIGIT;
6332 } while (position < stri->size && okay);
6333 if (likely(okay)) {
6334 memset(&result->bigdigits[result->size], 0,
6335 (size_t) (result_size - result->size) * sizeof(bigDigitType));
6336 result->size = result_size;
6337 if (negative) {
6338 negate_positive_big(result);
6339 } /* if */
6340 result = normalize(result);
6341 } else {
6342 FREE_BIG(result, result_size);
6343 logError(printf("bigParse(\"%s\"): "
6344 "Illegal digit.\n",
6345 striAsUnquotedCStri(stri)););
6346 raise_error(RANGE_ERROR);
6347 result = NULL;
6348 } /* if */
6349 } /* if */
6350 } /* if */
6351 logFunction(printf("bigParse --> %s\n", bigHexCStri(result)););
6352 return result;
6353 } /* bigParse */
6354
6355
6356
6357 /**
6358 * Convert a numeric string, with a specified radix, to a 'bigInteger'.
6359 * The numeric string must contain the representation of an integer
6360 * in the specified radix. It consists of an optional + or - sign,
6361 * followed by a sequence of digits in the specified radix. Digit values
6362 * from 10 upward can be encoded with upper or lower case letters.
6363 * E.g.: 10 can be encoded with A or a, 11 with B or b, etc. Other
6364 * characters as well as leading or trailing whitespace characters
6365 * are not allowed.
6366 * @param stri Numeric string with integer in the specified radix.
6367 * @param base Radix of the integer in the 'stri' parameter.
6368 * @return the 'bigInteger' result of the conversion.
6369 * @exception RANGE_ERROR If base < 2 or base > 36 holds or
6370 * the string does not contain an integer
6371 * literal with the specified base.
6372 * @exception MEMORY_ERROR Not enough memory to represent the result.
6373 */
bigParseBased(const const_striType stri,intType base)6374 bigIntType bigParseBased (const const_striType stri, intType base)
6375
6376 {
6377 bigIntType result;
6378
6379 /* bigParseBased */
6380 logFunction(printf("bigParseBased(\"%s\", " FMT_D ")\n",
6381 striAsUnquotedCStri(stri), base););
6382 switch (castIntTypeForSwitch(base)) {
6383 /* Cases sorted by probability. */
6384 case 16: result = bigParseBasedPow2(stri, 4); break;
6385 case 8: result = bigParseBasedPow2(stri, 3); break;
6386 case 10: result = bigParse(stri); break;
6387 case 2: result = bigParseBasedPow2(stri, 1); break;
6388 case 4: result = bigParseBasedPow2(stri, 2); break;
6389 case 32: result = bigParseBasedPow2(stri, 5); break;
6390 default:
6391 if (unlikely(base < 2 || base > 36)) {
6392 logError(printf("bigParseBased(\"%s\", " FMT_D "): "
6393 "Base not in allowed range.\n",
6394 striAsUnquotedCStri(stri), base););
6395 raise_error(RANGE_ERROR);
6396 result = NULL;
6397 } else {
6398 result = bigParseBased2To36(stri, (unsigned int) base);
6399 } /* if */
6400 break;
6401 } /* switch */
6402 logFunction(printf("bigParseBased --> %s\n", bigHexCStri(result)););
6403 return result;
6404 } /* bigParseBased */
6405
6406
6407
6408 /**
6409 * Predecessor of a 'bigInteger' number.
6410 * pred(A) is equivalent to A-1 .
6411 * @return big1 - 1 .
6412 * @exception MEMORY_ERROR Not enough memory to represent the result.
6413 */
bigPred(const const_bigIntType big1)6414 bigIntType bigPred (const const_bigIntType big1)
6415
6416 {
6417 memSizeType pos;
6418 bigIntType resized_predecessor;
6419 bigIntType predecessor;
6420
6421 /* bigPred */
6422 logFunction(printf("bigPred(%s)\n", bigHexCStri(big1)););
6423 if (unlikely(!ALLOC_BIG_SIZE_OK(predecessor, big1->size))) {
6424 raise_error(MEMORY_ERROR);
6425 } else {
6426 predecessor->size = big1->size;
6427 pos = 0;
6428 if (big1->bigdigits[pos] == 0) {
6429 if (big1->size == 1) {
6430 predecessor->bigdigits[pos] = BIGDIGIT_MASK;
6431 pos++;
6432 } else {
6433 do {
6434 predecessor->bigdigits[pos] = BIGDIGIT_MASK;
6435 pos++;
6436 } while (big1->bigdigits[pos] == 0);
6437 /* memset(predecessor->bigdigits, 0xFF, pos * sizeof(bigDigitType)); */
6438 } /* if */
6439 } /* if */
6440 if (pos < big1->size) {
6441 predecessor->bigdigits[pos] = big1->bigdigits[pos] - 1;
6442 pos++;
6443 memcpy(&predecessor->bigdigits[pos], &big1->bigdigits[pos],
6444 (big1->size - pos) * sizeof(bigDigitType));
6445 pos = big1->size;
6446 /* while (pos < big1->size) {
6447 predecessor->bigdigits[pos] = big1->bigdigits[pos];
6448 pos++;
6449 } ** while */
6450 } /* if */
6451 if (!IS_NEGATIVE(predecessor->bigdigits[pos - 1])) {
6452 if (IS_NEGATIVE(big1->bigdigits[pos - 1])) {
6453 REALLOC_BIG_CHECK_SIZE(resized_predecessor, predecessor, pos, pos + 1);
6454 if (unlikely(resized_predecessor == NULL)) {
6455 FREE_BIG(predecessor, pos);
6456 raise_error(MEMORY_ERROR);
6457 predecessor = NULL;
6458 } else {
6459 predecessor = resized_predecessor;
6460 COUNT3_BIG(pos, pos + 1);
6461 predecessor->size++;
6462 predecessor->bigdigits[pos] = BIGDIGIT_MASK;
6463 } /* if */
6464 } else if (predecessor->bigdigits[pos - 1] == 0 &&
6465 pos >= 2 && !IS_NEGATIVE(predecessor->bigdigits[pos - 2])) {
6466 REALLOC_BIG_SIZE_OK(resized_predecessor, predecessor, pos, pos - 1);
6467 /* Avoid a MEMORY_ERROR in the strange case */
6468 /* if a 'realloc' which shrinks memory fails. */
6469 if (likely(resized_predecessor != NULL)) {
6470 predecessor = resized_predecessor;
6471 } /* if */
6472 COUNT3_BIG(pos, pos - 1);
6473 predecessor->size--;
6474 } /* if */
6475 } /* if */
6476 } /* if */
6477 logFunction(printf("bigPred --> %s\n", bigHexCStri(predecessor)););
6478 return predecessor;
6479 } /* bigPred */
6480
6481
6482
6483 /**
6484 * Returns a signed big integer decremented by 1.
6485 * Big1 is assumed to be a temporary value which is reused.
6486 */
bigPredTemp(bigIntType big1)6487 bigIntType bigPredTemp (bigIntType big1)
6488
6489 {
6490 memSizeType pos = 0;
6491 boolType negative;
6492 bigIntType resized_big1;
6493
6494 /* bigPredTemp */
6495 logFunction(printf("bigPredTemp(%s)\n", bigHexCStri(big1)););
6496 negative = IS_NEGATIVE(big1->bigdigits[big1->size - 1]);
6497 if (big1->bigdigits[pos] == 0) {
6498 if (big1->size == 1) {
6499 big1->bigdigits[pos] = BIGDIGIT_MASK;
6500 pos++;
6501 } else {
6502 do {
6503 big1->bigdigits[pos] = BIGDIGIT_MASK;
6504 pos++;
6505 } while (big1->bigdigits[pos] == 0);
6506 /* memset(big1->bigdigits, 0xFF, pos * sizeof(bigDigitType)); */
6507 } /* if */
6508 } /* if */
6509 if (pos < big1->size) {
6510 big1->bigdigits[pos]--;
6511 } /* if */
6512 pos = big1->size;
6513 if (!IS_NEGATIVE(big1->bigdigits[pos - 1])) {
6514 if (negative) {
6515 REALLOC_BIG_CHECK_SIZE(resized_big1, big1, pos, pos + 1);
6516 if (unlikely(resized_big1 == NULL)) {
6517 FREE_BIG(big1, big1->size);
6518 raise_error(MEMORY_ERROR);
6519 big1 = NULL;
6520 } else {
6521 big1 = resized_big1;
6522 COUNT3_BIG(pos, pos + 1);
6523 big1->size++;
6524 big1->bigdigits[pos] = BIGDIGIT_MASK;
6525 } /* if */
6526 } else if (big1->bigdigits[pos - 1] == 0 &&
6527 pos >= 2 && !IS_NEGATIVE(big1->bigdigits[pos - 2])) {
6528 REALLOC_BIG_SIZE_OK(resized_big1, big1, pos, pos - 1);
6529 /* Avoid a MEMORY_ERROR in the strange case */
6530 /* if a 'realloc' which shrinks memory fails. */
6531 if (likely(resized_big1 != NULL)) {
6532 big1 = resized_big1;
6533 } /* if */
6534 COUNT3_BIG(pos, pos - 1);
6535 big1->size--;
6536 } /* if */
6537 } /* if */
6538 logFunction(printf("bigPredTemp --> %s\n", bigHexCStri(big1)););
6539 return big1;
6540 } /* bigPredTemp */
6541
6542
6543
6544 /**
6545 * Convert a big integer number to a string using a radix.
6546 * The conversion uses the numeral system with the given base.
6547 * Digit values from 10 upward are encoded with letters.
6548 * For negative numbers a minus sign is prepended.
6549 * @param big1 BigInteger number to be converted.
6550 * @param upperCase Decides about the letter case.
6551 * @return the string result of the conversion.
6552 * @exception RANGE_ERROR If base < 2 or base > 36 holds.
6553 * @exception MEMORY_ERROR Not enough memory to represent the result.
6554 */
bigRadix(const const_bigIntType big1,intType base,boolType upperCase)6555 striType bigRadix (const const_bigIntType big1, intType base,
6556 boolType upperCase)
6557
6558 {
6559 striType result;
6560
6561 /* bigRadix */
6562 logFunction(printf("bigRadix(%s, " FMT_D ", %d)\n",
6563 bigHexCStri(big1), base, upperCase););
6564 switch (castIntTypeForSwitch(base)) {
6565 /* Cases sorted by probability. */
6566 case 16: result = bigRadixPow2(big1, 4, 0xf, upperCase); break;
6567 case 8: result = bigRadixPow2(big1, 3, 0x7, upperCase); break;
6568 case 10: result = bigStr(big1); break;
6569 case 2: result = bigRadixPow2(big1, 1, 0x1, upperCase); break;
6570 case 4: result = bigRadixPow2(big1, 2, 0x3, upperCase); break;
6571 case 32: result = bigRadixPow2(big1, 5, 0x1f, upperCase); break;
6572 default:
6573 if (unlikely(base < 2 || base > 36)) {
6574 logError(printf("bigRadix((%s, " FMT_D ", %d): "
6575 "Base not in allowed range.\n",
6576 bigHexCStri(big1), base, upperCase););
6577 raise_error(RANGE_ERROR);
6578 result = NULL;
6579 } else {
6580 result = bigRadix2To36(big1, (unsigned int) base, upperCase);
6581 } /* if */
6582 break;
6583 } /* switch */
6584 logFunction(printf("bigRadix --> \"%s\"\n", striAsUnquotedCStri(result)););
6585 return result;
6586 } /* bigRadix */
6587
6588
6589
6590 /**
6591 * Compute pseudo-random number in the range [low, high].
6592 * The random values are uniform distributed. The memory for
6593 * the result is requested and the normalized result is returned.
6594 * @return a random number such that low <= rand(low, high) and
6595 * rand(low, high) <= high holds.
6596 * @exception RANGE_ERROR The range is empty (low > high holds).
6597 * @exception MEMORY_ERROR Not enough memory to represent the result.
6598 */
bigRand(const const_bigIntType low,const const_bigIntType high)6599 bigIntType bigRand (const const_bigIntType low,
6600 const const_bigIntType high)
6601
6602 {
6603 bigIntType scale_limit;
6604 int usedBits;
6605 bigDigitType mask;
6606 memSizeType pos;
6607 doubleBigDigitType random_number = 0;
6608 memSizeType randomNumber_size;
6609 bigIntType randomNumber;
6610
6611 /* bigRand */
6612 logFunction(printf("bigRand(%s, %s)\n", bigHexCStri(low), bigHexCStri(high)););
6613 if (unlikely(bigCmp(low, high) > 0)) {
6614 logError(printf("bigRand(%s, %s): "
6615 "The range is empty (low > high holds).\n",
6616 bigHexCStri(low), bigHexCStri(high)););
6617 raise_error(RANGE_ERROR);
6618 randomNumber = NULL;
6619 } else {
6620 scale_limit = bigSbtr(high, low);
6621 if (low->size > scale_limit->size) {
6622 randomNumber_size = low->size + 1;
6623 } else {
6624 randomNumber_size = scale_limit->size + 1;
6625 } /* if */
6626 if (unlikely(!ALLOC_BIG(randomNumber, randomNumber_size))) {
6627 raise_error(MEMORY_ERROR);
6628 randomNumber = NULL;
6629 } else {
6630 memset(&randomNumber->bigdigits[scale_limit->size], 0,
6631 (size_t) (randomNumber_size - scale_limit->size) * sizeof(bigDigitType));
6632 randomNumber->size = scale_limit->size;
6633 usedBits = digitMostSignificantBit(scale_limit->bigdigits[scale_limit->size - 1]) + 1;
6634 if (usedBits == 0) {
6635 mask = 0;
6636 } else {
6637 mask = ((bigDigitType) BIGDIGIT_MASK) >> (BIGDIGIT_SIZE - (memSizeType) (usedBits));
6638 } /* if */
6639 do {
6640 pos = 0;
6641 do {
6642 if (random_number == 0) {
6643 random_number = uintRand();
6644 } /* if */
6645 randomNumber->bigdigits[pos] = (bigDigitType) (random_number & BIGDIGIT_MASK);
6646 random_number >>= BIGDIGIT_SIZE;
6647 pos++;
6648 } while (pos < scale_limit->size);
6649 randomNumber->bigdigits[pos - 1] &= mask;
6650 } while (bigCmp(randomNumber, scale_limit) > 0);
6651 randomNumber->size = randomNumber_size;
6652 bigAddTo(randomNumber, low);
6653 randomNumber = normalize(randomNumber);
6654 FREE_BIG(scale_limit, scale_limit->size);
6655 } /* if */
6656 } /* if */
6657 logFunction(printf("bigRand --> %s\n", bigHexCStri(randomNumber)););
6658 return randomNumber;
6659 } /* bigRand */
6660
6661
6662
6663 /**
6664 * Compute the remainder of the integer division bigDiv.
6665 * The remainder has the same sign as the dividend. The memory for the result
6666 * is requested and the normalized result is returned. If divisor has
6667 * just one digit or if dividend has less digits than divisor the
6668 * functions bigRem1() or bigRemSizeLess() are called. In the general case
6669 * the absolute values of dividend and divisor are taken. Then dividend is
6670 * extended by one leading zero digit. After that dividend and divisor
6671 * are shifted to the left such that the most significant bit
6672 * of divisor is set. This fulfills the preconditions for calling
6673 * uBigRem() which does the main work of the division. Afterwards
6674 * the result must be shifted to the right to get the remainder.
6675 * @return the remainder of the integer division.
6676 * @exception NUMERIC_ERROR If a division by zero occurs.
6677 */
bigRem(const const_bigIntType dividend,const const_bigIntType divisor)6678 bigIntType bigRem (const const_bigIntType dividend, const const_bigIntType divisor)
6679
6680 {
6681 boolType negative = FALSE;
6682 bigIntType divisor_help;
6683 unsigned int shift;
6684 bigIntType remainder;
6685
6686 /* bigRem */
6687 logFunction(printf("bigRem(%s, ", bigHexCStri(dividend));
6688 printf("%s)\n", bigHexCStri(divisor)););
6689 if (divisor->size == 1) {
6690 remainder = bigRem1(dividend, divisor->bigdigits[0]);
6691 } else if (dividend->size < divisor->size) {
6692 remainder = bigRemSizeLess(dividend, divisor);
6693 } else {
6694 if (unlikely(!ALLOC_BIG_CHECK_SIZE(remainder, dividend->size + 2))) {
6695 raise_error(MEMORY_ERROR);
6696 return NULL;
6697 } else {
6698 if (IS_NEGATIVE(dividend->bigdigits[dividend->size - 1])) {
6699 negative = TRUE;
6700 positive_copy_of_negative_big(remainder, dividend);
6701 } else {
6702 remainder->size = dividend->size;
6703 memcpy(remainder->bigdigits, dividend->bigdigits,
6704 (size_t) dividend->size * sizeof(bigDigitType));
6705 } /* if */
6706 remainder->bigdigits[remainder->size] = 0;
6707 remainder->size++;
6708 } /* if */
6709 if (unlikely(!ALLOC_BIG_CHECK_SIZE(divisor_help, divisor->size + 1))) {
6710 FREE_BIG(remainder, dividend->size + 2);
6711 raise_error(MEMORY_ERROR);
6712 return NULL;
6713 } else {
6714 if (IS_NEGATIVE(divisor->bigdigits[divisor->size - 1])) {
6715 positive_copy_of_negative_big(divisor_help, divisor);
6716 } else {
6717 divisor_help->size = divisor->size;
6718 memcpy(divisor_help->bigdigits, divisor->bigdigits,
6719 (size_t) divisor->size * sizeof(bigDigitType));
6720 } /* if */
6721 } /* if */
6722 shift = (unsigned int)
6723 (digitMostSignificantBit(divisor_help->bigdigits[divisor_help->size - 1]) + 1);
6724 if (shift == 0) {
6725 /* The most significant digit of divisor_help is 0. Just ignore it */
6726 remainder->size--;
6727 divisor_help->size--;
6728 if (divisor_help->size == 1) {
6729 remainder->bigdigits[0] = uBigRem1(remainder, divisor_help->bigdigits[0]);
6730 memset(&remainder->bigdigits[1], 0,
6731 (size_t) (remainder->size - 1) * sizeof(bigDigitType));
6732 } else {
6733 uBigRem(remainder, divisor_help);
6734 } /* if */
6735 remainder->bigdigits[remainder->size] = 0;
6736 divisor_help->size++;
6737 } else {
6738 shift = BIGDIGIT_SIZE - shift;
6739 uBigLShift(remainder, shift);
6740 uBigLShift(divisor_help, shift);
6741 uBigRem(remainder, divisor_help);
6742 uBigRShift(remainder, shift);
6743 } /* if */
6744 remainder->bigdigits[dividend->size + 1] = 0;
6745 remainder->size = dividend->size + 2;
6746 if (negative) {
6747 negate_positive_big(remainder);
6748 } /* if */
6749 remainder = normalize(remainder);
6750 FREE_BIG(divisor_help, divisor->size + 1);
6751 } /* if */
6752 logFunction(printf("bigRem --> %s\n", bigHexCStri(remainder)););
6753 return remainder;
6754 } /* bigRem */
6755
6756
6757
6758 /**
6759 * Shift a 'bigInteger' number right by rshift bits.
6760 * If rshift is negative a left shift is done instead.
6761 * A >> B is equivalent to A mdiv 2_ ** B if B >= 0 holds.
6762 * A >> B is equivalent to A * 2_ ** -B if B < 0 holds.
6763 * @return the right shifted number.
6764 * @exception MEMORY_ERROR Not enough memory to represent the result.
6765 */
bigRShift(const const_bigIntType big1,const intType rshift)6766 bigIntType bigRShift (const const_bigIntType big1, const intType rshift)
6767
6768 {
6769 memSizeType size_reduction;
6770 unsigned int digit_rshift;
6771 unsigned int digit_lshift;
6772 bigDigitType digit_mask;
6773 bigDigitType low_digit;
6774 bigDigitType high_digit;
6775 const bigDigitType *source_digits;
6776 bigDigitType *dest_digits;
6777 memSizeType pos;
6778 memSizeType result_size;
6779 bigIntType result;
6780
6781 /* bigRShift */
6782 logFunction(printf("bigRShift(%s, " FMT_D ")\n",
6783 bigHexCStri(big1), rshift););
6784 if (unlikely(rshift < 0)) {
6785 if (unlikely(TWOS_COMPLEMENT_INTTYPE && rshift == INTTYPE_MIN)) {
6786 result = bigLShift(big1, INTTYPE_MAX);
6787 if (result != NULL) {
6788 bigLShiftAssign(&result, 1);
6789 } /* if */
6790 } else {
6791 result = bigLShift(big1, -rshift);
6792 } /* if */
6793 } else if (big1->size <= (uintType) rshift >> BIGDIGIT_LOG2_SIZE) {
6794 if (unlikely(!ALLOC_BIG_SIZE_OK(result, 1))) {
6795 raise_error(MEMORY_ERROR);
6796 } else {
6797 result->size = 1;
6798 if (IS_NEGATIVE(big1->bigdigits[big1->size - 1])) {
6799 result->bigdigits[0] = BIGDIGIT_MASK;
6800 } else {
6801 result->bigdigits[0] = 0;
6802 } /* if */
6803 } /* if */
6804 } else {
6805 size_reduction = (memSizeType) ((uintType) rshift >> BIGDIGIT_LOG2_SIZE);
6806 result_size = big1->size - size_reduction;
6807 if ((rshift & BIGDIGIT_SIZE_MASK) == 0) {
6808 if (unlikely(!ALLOC_BIG_SIZE_OK(result, result_size))) {
6809 raise_error(MEMORY_ERROR);
6810 } else {
6811 result->size = result_size;
6812 memcpy(result->bigdigits, &big1->bigdigits[size_reduction],
6813 (size_t) result_size * sizeof(bigDigitType));
6814 } /* if */
6815 } else {
6816 digit_rshift = (unsigned int) ((uintType) rshift & BIGDIGIT_SIZE_MASK);
6817 digit_lshift = BIGDIGIT_SIZE - digit_rshift;
6818 if (result_size > 1) {
6819 high_digit = big1->bigdigits[big1->size - 1];
6820 if (IS_NEGATIVE(high_digit)) {
6821 digit_mask = (BIGDIGIT_MASK << (digit_rshift - 1)) & BIGDIGIT_MASK;
6822 if ((digit_rshift == 1 && high_digit == BIGDIGIT_MASK) ||
6823 (high_digit & digit_mask) == digit_mask) {
6824 result_size--;
6825 } /* if */
6826 } else {
6827 if ((digit_rshift == 1 && high_digit == 0) ||
6828 high_digit >> (digit_rshift - 1) == 0) {
6829 result_size--;
6830 } /* if */
6831 } /* if */
6832 } /* if */
6833 if (unlikely(!ALLOC_BIG_SIZE_OK(result, result_size))) {
6834 raise_error(MEMORY_ERROR);
6835 } else {
6836 result->size = result_size;
6837 source_digits = &big1->bigdigits[size_reduction];
6838 dest_digits = result->bigdigits;
6839 high_digit = *source_digits++;
6840 low_digit = high_digit >> digit_rshift;
6841 for (pos = big1->size - size_reduction - 1; pos != 0; pos--) {
6842 high_digit = *source_digits++;
6843 *dest_digits++ = low_digit | ((high_digit << digit_lshift) & BIGDIGIT_MASK);
6844 low_digit = high_digit >> digit_rshift;
6845 } /* for */
6846 if ((memSizeType) (dest_digits - result->bigdigits) < result_size) {
6847 if (IS_NEGATIVE(high_digit)) {
6848 *dest_digits = low_digit | ((BIGDIGIT_MASK << digit_lshift) & BIGDIGIT_MASK);
6849 } else {
6850 *dest_digits = low_digit;
6851 } /* if */
6852 } /* if */
6853 } /* if */
6854 } /* if */
6855 } /* if */
6856 logFunction(printf("bigRShift --> %s\n", bigHexCStri(result)););
6857 return result;
6858 } /* bigRShift */
6859
6860
6861
6862 /**
6863 * Shift a number right by rshift bits and assign the result back to number.
6864 * If rshift is negative a left shift is done instead.
6865 * @exception MEMORY_ERROR Not enough memory to represent the new value.
6866 */
bigRShiftAssign(bigIntType * const big_variable,intType rshift)6867 void bigRShiftAssign (bigIntType *const big_variable, intType rshift)
6868
6869 {
6870 bigIntType big1;
6871 memSizeType size_reduction;
6872 unsigned int digit_rshift;
6873 unsigned int digit_lshift;
6874 bigDigitType low_digit;
6875 bigDigitType high_digit;
6876 const bigDigitType *source_digits;
6877 bigDigitType *dest_digits;
6878 bigIntType resized_big1;
6879 memSizeType pos;
6880 memSizeType big1_size;
6881
6882 /* bigRShiftAssign */
6883 logFunction(printf("bigRShiftAssign(%s, " FMT_D ")\n",
6884 bigHexCStri(*big_variable), rshift););
6885 if (unlikely(rshift < 0)) {
6886 if (unlikely(TWOS_COMPLEMENT_INTTYPE && rshift == INTTYPE_MIN)) {
6887 bigLShiftAssign(big_variable, INTTYPE_MAX);
6888 bigLShiftAssign(big_variable, 1);
6889 } else {
6890 bigLShiftAssign(big_variable, -rshift);
6891 } /* if */
6892 } else {
6893 big1 = *big_variable;
6894 if (big1->size <= (uintType) rshift >> BIGDIGIT_LOG2_SIZE) {
6895 if (unlikely(!ALLOC_BIG_SIZE_OK(*big_variable, 1))) {
6896 raise_error(MEMORY_ERROR);
6897 } else {
6898 (*big_variable)->size = 1;
6899 if (IS_NEGATIVE(big1->bigdigits[big1->size - 1])) {
6900 (*big_variable)->bigdigits[0] = BIGDIGIT_MASK;
6901 } else {
6902 (*big_variable)->bigdigits[0] = 0;
6903 } /* if */
6904 FREE_BIG(big1, big1->size);
6905 } /* if */
6906 } else {
6907 size_reduction = (memSizeType) ((uintType) rshift >> BIGDIGIT_LOG2_SIZE);
6908 if ((rshift & BIGDIGIT_SIZE_MASK) == 0) {
6909 if (rshift != 0) {
6910 big1_size = big1->size;
6911 memmove(big1->bigdigits, &big1->bigdigits[size_reduction],
6912 (size_t) (big1_size - size_reduction) * sizeof(bigDigitType));
6913 REALLOC_BIG_SIZE_OK(resized_big1, big1, big1_size, big1_size - size_reduction);
6914 /* Avoid a MEMORY_ERROR in the strange case */
6915 /* if a 'realloc' which shrinks memory fails. */
6916 if (likely(resized_big1 != NULL)) {
6917 big1 = resized_big1;
6918 *big_variable = big1;
6919 } /* if */
6920 COUNT3_BIG(big1_size, big1_size - size_reduction);
6921 big1->size -= size_reduction;
6922 } /* if */
6923 } else {
6924 digit_rshift = (unsigned int) ((uintType) rshift & BIGDIGIT_SIZE_MASK);
6925 digit_lshift = BIGDIGIT_SIZE - digit_rshift;
6926 source_digits = &big1->bigdigits[size_reduction];
6927 dest_digits = big1->bigdigits;
6928 high_digit = *source_digits++;
6929 low_digit = high_digit >> digit_rshift;
6930 for (pos = big1->size - size_reduction - 1; pos != 0; pos--) {
6931 high_digit = *source_digits++;
6932 *dest_digits++ = low_digit | ((high_digit << digit_lshift) & BIGDIGIT_MASK);
6933 low_digit = high_digit >> digit_rshift;
6934 } /* for */
6935 if (IS_NEGATIVE(high_digit)) {
6936 *dest_digits = low_digit | ((BIGDIGIT_MASK << digit_lshift) & BIGDIGIT_MASK);
6937 if (*dest_digits == BIGDIGIT_MASK) {
6938 if (size_reduction == 0) {
6939 *big_variable = normalize(big1);
6940 } else {
6941 pos = big1->size - size_reduction;
6942 if (pos >= 2 && IS_NEGATIVE(big1->bigdigits[pos - 2])) {
6943 pos--;
6944 } /* if */
6945 REALLOC_BIG_SIZE_OK(resized_big1, big1, big1->size, pos);
6946 /* Avoid a MEMORY_ERROR in the strange case */
6947 /* if a 'realloc' which shrinks memory fails. */
6948 if (likely(resized_big1 != NULL)) {
6949 big1 = resized_big1;
6950 *big_variable = big1;
6951 } /* if */
6952 COUNT3_BIG(big1->size, pos);
6953 big1->size = pos;
6954 size_reduction = 0;
6955 } /* if */
6956 } /* if */
6957 } else {
6958 *dest_digits = low_digit;
6959 if (low_digit == 0) {
6960 if (size_reduction == 0) {
6961 *big_variable = normalize(big1);
6962 } else {
6963 pos = big1->size - size_reduction;
6964 if (pos >= 2 && !IS_NEGATIVE(big1->bigdigits[pos - 2])) {
6965 pos--;
6966 } /* if */
6967 REALLOC_BIG_SIZE_OK(resized_big1, big1, big1->size, pos);
6968 /* Avoid a MEMORY_ERROR in the strange case */
6969 /* if a 'realloc' which shrinks memory fails. */
6970 if (likely(resized_big1 != NULL)) {
6971 big1 = resized_big1;
6972 *big_variable = big1;
6973 } /* if */
6974 COUNT3_BIG(big1->size, pos);
6975 big1->size = pos;
6976 size_reduction = 0;
6977 } /* if */
6978 } /* if */
6979 } /* if */
6980 if (size_reduction != 0) {
6981 big1_size = big1->size;
6982 REALLOC_BIG_SIZE_OK(resized_big1, big1, big1_size, big1_size - size_reduction);
6983 /* Avoid a MEMORY_ERROR in the strange case */
6984 /* if a 'realloc' which shrinks memory fails. */
6985 if (likely(resized_big1 != NULL)) {
6986 big1 = resized_big1;
6987 *big_variable = big1;
6988 } /* if */
6989 COUNT3_BIG(big1_size, big1_size - size_reduction);
6990 big1->size -= size_reduction;
6991 } /* if */
6992 } /* if */
6993 } /* if */
6994 } /* if */
6995 logFunction(printf("bigRShiftAssign --> %s\n", bigHexCStri(*big_variable)););
6996 } /* bigRShiftAssign */
6997
6998
6999
7000 /**
7001 * Compute the subtraction of two 'bigInteger' numbers.
7002 * @return the difference of the two numbers.
7003 * @exception MEMORY_ERROR Not enough memory to represent the result.
7004 */
bigSbtr(const const_bigIntType minuend,const const_bigIntType subtrahend)7005 bigIntType bigSbtr (const const_bigIntType minuend, const const_bigIntType subtrahend)
7006
7007 {
7008 memSizeType pos;
7009 doubleBigDigitType carry = 1;
7010 doubleBigDigitType minuend_sign;
7011 doubleBigDigitType subtrahend_sign;
7012 bigIntType difference;
7013
7014 /* bigSbtr */
7015 logFunction(printf("bigSbtr(%s,", bigHexCStri(minuend));
7016 printf("%s)\n", bigHexCStri(subtrahend)););
7017 if (minuend->size >= subtrahend->size) {
7018 if (unlikely(!ALLOC_BIG_CHECK_SIZE(difference, minuend->size + 1))) {
7019 raise_error(MEMORY_ERROR);
7020 return NULL;
7021 } else {
7022 pos = 0;
7023 do {
7024 carry += (doubleBigDigitType) minuend->bigdigits[pos] +
7025 (~subtrahend->bigdigits[pos] & BIGDIGIT_MASK);
7026 difference->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
7027 carry >>= BIGDIGIT_SIZE;
7028 pos++;
7029 } while (pos < subtrahend->size);
7030 subtrahend_sign = IS_NEGATIVE(subtrahend->bigdigits[pos - 1]) ? 0 : BIGDIGIT_MASK;
7031 for (; pos < minuend->size; pos++) {
7032 carry += minuend->bigdigits[pos] + subtrahend_sign;
7033 difference->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
7034 carry >>= BIGDIGIT_SIZE;
7035 } /* for */
7036 if (IS_NEGATIVE(minuend->bigdigits[pos - 1])) {
7037 subtrahend_sign--;
7038 } /* if */
7039 difference->bigdigits[pos] = (bigDigitType) ((carry + subtrahend_sign) & BIGDIGIT_MASK);
7040 difference->size = pos + 1;
7041 difference = normalize(difference);
7042 } /* if */
7043 } else {
7044 if (unlikely(!ALLOC_BIG_CHECK_SIZE(difference, subtrahend->size + 1))) {
7045 raise_error(MEMORY_ERROR);
7046 return NULL;
7047 } else {
7048 pos = 0;
7049 do {
7050 carry += (doubleBigDigitType) minuend->bigdigits[pos] +
7051 (~subtrahend->bigdigits[pos] & BIGDIGIT_MASK);
7052 difference->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
7053 carry >>= BIGDIGIT_SIZE;
7054 pos++;
7055 } while (pos < minuend->size);
7056 minuend_sign = IS_NEGATIVE(minuend->bigdigits[pos - 1]) ? BIGDIGIT_MASK : 0;
7057 for (; pos < subtrahend->size; pos++) {
7058 carry += minuend_sign + (~subtrahend->bigdigits[pos] & BIGDIGIT_MASK);
7059 difference->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
7060 carry >>= BIGDIGIT_SIZE;
7061 } /* for */
7062 subtrahend_sign = IS_NEGATIVE(subtrahend->bigdigits[pos - 1]) ? 0 : BIGDIGIT_MASK;
7063 if (IS_NEGATIVE(minuend->bigdigits[minuend->size - 1])) {
7064 subtrahend_sign--;
7065 } /* if */
7066 difference->bigdigits[pos] = (bigDigitType) ((carry + subtrahend_sign) & BIGDIGIT_MASK);
7067 difference->size = pos + 1;
7068 difference = normalize(difference);
7069 } /* if */
7070 } /* if */
7071 logFunction(printf("bigSbtr --> %s\n", bigHexCStri(difference)););
7072 return difference;
7073 } /* bigSbtr */
7074
7075
7076
7077 /**
7078 * Decrement a 'bigInteger' variable by a delta.
7079 * Subtracts delta from *big_variable. The operation is done in
7080 * place and *big_variable is only resized if necessary.
7081 * If the size of delta is smaller than *big_variable the
7082 * algorithm tries to save computations. Therefore there are
7083 * checks for carry != 0 and carry == 0.
7084 * In case the resizing fails the content of *big_variable
7085 * is freed and *big_variable is set to NULL.
7086 * @param delta The delta to be subtracted from *big_variable.
7087 * @exception MEMORY_ERROR If the resizing of *big_variable fails.
7088 */
bigSbtrAssign(bigIntType * const big_variable,const const_bigIntType delta)7089 void bigSbtrAssign (bigIntType *const big_variable, const const_bigIntType delta)
7090
7091 {
7092 bigIntType big1;
7093 memSizeType pos;
7094 memSizeType big1_size;
7095 boolType delta_negative;
7096 doubleBigDigitType carry = 1;
7097 doubleBigDigitType big1_sign;
7098 doubleBigDigitType delta_sign;
7099 bigIntType resized_big1;
7100
7101 /* bigSbtrAssign */
7102 logFunction(printf("bigSbtrAssign(%s,", bigHexCStri(*big_variable));
7103 printf("%s)\n", bigHexCStri(delta)););
7104 big1 = *big_variable;
7105 if (big1->size >= delta->size) {
7106 big1_size = big1->size;
7107 big1_sign = IS_NEGATIVE(big1->bigdigits[big1_size - 1]) ? BIGDIGIT_MASK : 0;
7108 /* It is possible that big1 == delta holds. Therefore the check */
7109 /* for negative delta must be done before big1 is changed. */
7110 delta_negative = IS_NEGATIVE(delta->bigdigits[delta->size - 1]);
7111 pos = 0;
7112 do {
7113 carry += (doubleBigDigitType) big1->bigdigits[pos] +
7114 (~delta->bigdigits[pos] & BIGDIGIT_MASK);
7115 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
7116 carry >>= BIGDIGIT_SIZE;
7117 pos++;
7118 } while (pos < delta->size);
7119 if (delta_negative) {
7120 for (; carry != 0 && pos < big1_size; pos++) {
7121 carry += big1->bigdigits[pos];
7122 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
7123 carry >>= BIGDIGIT_SIZE;
7124 } /* for */
7125 } else {
7126 for (; carry == 0 && pos < big1_size; pos++) {
7127 carry = (doubleBigDigitType) big1->bigdigits[pos] + BIGDIGIT_MASK;
7128 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
7129 carry >>= BIGDIGIT_SIZE;
7130 } /* for */
7131 carry += BIGDIGIT_MASK;
7132 } /* if */
7133 carry += big1_sign;
7134 carry &= BIGDIGIT_MASK;
7135 /* Now the only possible values for carry are 0 and BIGDIGIT_MASK. */
7136 if ((carry != 0 || IS_NEGATIVE(big1->bigdigits[big1_size - 1])) &&
7137 (carry != BIGDIGIT_MASK || !IS_NEGATIVE(big1->bigdigits[big1_size - 1]))) {
7138 REALLOC_BIG_CHECK_SIZE(resized_big1, big1, big1_size, big1_size + 1);
7139 if (unlikely(resized_big1 == NULL)) {
7140 FREE_BIG(big1, big1_size);
7141 *big_variable = NULL;
7142 raise_error(MEMORY_ERROR);
7143 } else {
7144 /* It is possible that big1 == delta holds. Since */
7145 /* 'delta' is not used after realloc() enlarged */
7146 /* 'big1' a correction of delta is not necessary. */
7147 big1 = resized_big1;
7148 COUNT3_BIG(big1_size, big1_size + 1);
7149 big1->size++;
7150 big1->bigdigits[big1_size] = (bigDigitType) (carry);
7151 *big_variable = big1;
7152 } /* if */
7153 } else {
7154 *big_variable = normalize(big1);
7155 } /* if */
7156 } else {
7157 REALLOC_BIG_CHECK_SIZE(resized_big1, big1, big1->size, delta->size + 1);
7158 if (unlikely(resized_big1 == NULL)) {
7159 FREE_BIG(big1, big1->size);
7160 *big_variable = NULL;
7161 raise_error(MEMORY_ERROR);
7162 } else {
7163 big1 = resized_big1;
7164 COUNT3_BIG(big1->size, delta->size + 1);
7165 big1_sign = IS_NEGATIVE(big1->bigdigits[big1->size - 1]) ? BIGDIGIT_MASK : 0;
7166 pos = 0;
7167 do {
7168 carry += (doubleBigDigitType) big1->bigdigits[pos] +
7169 (~delta->bigdigits[pos] & BIGDIGIT_MASK);
7170 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
7171 carry >>= BIGDIGIT_SIZE;
7172 pos++;
7173 } while (pos < big1->size);
7174 delta_sign = IS_NEGATIVE(delta->bigdigits[delta->size - 1]) ? 0 : BIGDIGIT_MASK;
7175 for (; pos < delta->size; pos++) {
7176 carry += big1_sign + (~delta->bigdigits[pos] & BIGDIGIT_MASK);
7177 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
7178 carry >>= BIGDIGIT_SIZE;
7179 } /* for */
7180 carry += big1_sign + delta_sign;
7181 big1->bigdigits[pos] = (bigDigitType) (carry & BIGDIGIT_MASK);
7182 big1->size = pos + 1;
7183 *big_variable = normalize(big1);
7184 } /* if */
7185 } /* if */
7186 logFunction(printf("bigSbtrAssign --> %s\n", bigHexCStri(*big_variable)););
7187 } /* bigSbtrAssign */
7188
7189
7190
7191 /**
7192 * Compute the subtraction of two 'bigInteger' numbers.
7193 * Minuend is assumed to be a temporary value which is reused.
7194 * @return the difference of the two numbers in 'minuend'.
7195 */
bigSbtrTemp(bigIntType minuend,const_bigIntType subtrahend)7196 bigIntType bigSbtrTemp (bigIntType minuend, const_bigIntType subtrahend)
7197
7198 { /* bigSbtrTemp */
7199 bigSbtrAssign(&minuend, subtrahend);
7200 return minuend;
7201 } /* bigSbtrTemp */
7202
7203
7204
7205 /**
7206 * Compute the square of a 'bigInteger'.
7207 * This function is used by the compiler to optimize
7208 * multiplication and exponentiation operations.
7209 * @return the square of big1.
7210 * @exception MEMORY_ERROR Not enough memory to represent the result.
7211 */
bigSquare(const_bigIntType big1)7212 bigIntType bigSquare (const_bigIntType big1)
7213
7214 {
7215 bigIntType big1_help = NULL;
7216 bigIntType square;
7217
7218 /* bigSquare */
7219 logFunction(printf("bigSquare(%s)\n", bigHexCStri(big1)););
7220 if (IS_NEGATIVE(big1->bigdigits[big1->size - 1])) {
7221 big1_help = alloc_positive_copy_of_negative_big(big1);
7222 big1 = big1_help;
7223 if (unlikely(big1_help == NULL)) {
7224 raise_error(MEMORY_ERROR);
7225 return NULL;
7226 } /* if */
7227 } /* if */
7228 /* printf("bigSquare(" FMT_U_MEM ")\n", big1->size); */
7229 square = uBigSquareK(big1);
7230 if (big1_help != NULL) {
7231 FREE_BIG(big1_help, big1_help->size);
7232 } /* if */
7233 if (unlikely(square == NULL)) {
7234 raise_error(MEMORY_ERROR);
7235 } /* if */
7236 logFunction(printf("bigSquare --> %s\n", bigHexCStri(square)););
7237 return square;
7238 } /* bigSquare */
7239
7240
7241
7242 /**
7243 * Convert a 'bigInteger' number to a string.
7244 * The number is converted to a string with decimal representation.
7245 * For negative numbers a minus sign is prepended.
7246 * @return the string result of the conversion.
7247 * @exception MEMORY_ERROR Not enough memory to represent the result.
7248 */
bigStr(const const_bigIntType big1)7249 striType bigStr (const const_bigIntType big1)
7250
7251 {
7252 bigIntType unsigned_big;
7253 memSizeType pos;
7254 memSizeType result_size;
7255 memSizeType final_result_size;
7256 striType resized_result;
7257 striType result;
7258
7259 /* bigStr */
7260 logFunction(printf("bigStr(%s)\n", bigHexCStri(big1)););
7261 if (unlikely((MAX_STRI_LEN <= (MAX_MEMSIZETYPE - 1) / OCTAL_DIGIT_BITS + 2 &&
7262 big1->size > ((MAX_STRI_LEN - 2) * OCTAL_DIGIT_BITS + 1) / BIGDIGIT_SIZE) ||
7263 big1->size > MAX_MEMSIZETYPE / BIGDIGIT_SIZE)) {
7264 raise_error(MEMORY_ERROR);
7265 result = NULL;
7266 } else {
7267 /* The size of the result is estimated by computing the */
7268 /* number of octal digits plus one character for the sign. */
7269 result_size = (big1->size * BIGDIGIT_SIZE - 1) / OCTAL_DIGIT_BITS + 2;
7270 if (unlikely(!ALLOC_STRI_SIZE_OK(result, result_size))) {
7271 raise_error(MEMORY_ERROR);
7272 result = NULL;
7273 } else {
7274 if (IS_NEGATIVE(big1->bigdigits[big1->size - 1])) {
7275 unsigned_big = alloc_positive_copy_of_negative_big(big1);
7276 } else if (likely(ALLOC_BIG_SIZE_OK(unsigned_big, big1->size))) {
7277 unsigned_big->size = big1->size;
7278 memcpy(unsigned_big->bigdigits, big1->bigdigits,
7279 (size_t) big1->size * sizeof(bigDigitType));
7280 } /* if */
7281 if (unlikely(unsigned_big == NULL)) {
7282 FREE_STRI(result, result_size);
7283 raise_error(MEMORY_ERROR);
7284 result = NULL;
7285 } else {
7286 /* pos = basicToStri(unsigned_big, result, result_size - 1); */
7287 pos = binaryToStri(unsigned_big, result, (unsigned int)
7288 memSizeMostSignificantBit(result_size) + 1,
7289 FALSE, result_size - 1);
7290 FREE_BIG(unsigned_big, big1->size);
7291 pos++;
7292 if (IS_NEGATIVE(big1->bigdigits[big1->size - 1])) {
7293 final_result_size = result_size - pos + 1;
7294 result->mem[0] = '-';
7295 memmove(&result->mem[1], &result->mem[pos],
7296 (result_size - pos) * sizeof(strElemType));
7297 } else {
7298 final_result_size = result_size - pos;
7299 memmove(&result->mem[0], &result->mem[pos],
7300 (result_size - pos) * sizeof(strElemType));
7301 } /* if */
7302 result->size = final_result_size;
7303 if (final_result_size < result_size) {
7304 REALLOC_STRI_SIZE_SMALLER(resized_result, result, result_size, final_result_size);
7305 if (unlikely(resized_result == NULL)) {
7306 FREE_STRI(result, result_size);
7307 raise_error(MEMORY_ERROR);
7308 result = NULL;
7309 } else {
7310 result = resized_result;
7311 COUNT3_STRI(result_size, final_result_size);
7312 } /* if */
7313 } /* if */
7314 } /* if */
7315 } /* if */
7316 } /* if */
7317 logFunction(printf("bigStr --> \"%s\"\n", striAsUnquotedCStri(result)););
7318 return result;
7319 } /* bigStr */
7320
7321
7322
7323 /**
7324 * Successor of a 'bigInteger' number.
7325 * succ(A) is equivalent to A+1 .
7326 * @return big1 + 1 .
7327 * @exception MEMORY_ERROR Not enough memory to represent the result.
7328 */
bigSucc(const const_bigIntType big1)7329 bigIntType bigSucc (const const_bigIntType big1)
7330
7331 {
7332 memSizeType pos;
7333 bigIntType resized_successor;
7334 bigIntType successor;
7335
7336 /* bigSucc */
7337 logFunction(printf("bigSucc(%s)\n", bigHexCStri(big1)););
7338 if (unlikely(!ALLOC_BIG_SIZE_OK(successor, big1->size))) {
7339 raise_error(MEMORY_ERROR);
7340 } else {
7341 successor->size = big1->size;
7342 pos = 0;
7343 if (big1->bigdigits[pos] == BIGDIGIT_MASK) {
7344 if (big1->size == 1) {
7345 successor->bigdigits[pos] = 0;
7346 pos++;
7347 } else {
7348 do {
7349 successor->bigdigits[pos] = 0;
7350 pos++;
7351 } while (big1->bigdigits[pos] == BIGDIGIT_MASK);
7352 /* memset(successor->bigdigits, 0, pos * sizeof(bigDigitType)); */
7353 } /* if */
7354 } /* if */
7355 if (pos < big1->size) {
7356 successor->bigdigits[pos] = big1->bigdigits[pos] + 1;
7357 pos++;
7358 memcpy(&successor->bigdigits[pos], &big1->bigdigits[pos],
7359 (big1->size - pos) * sizeof(bigDigitType));
7360 pos = big1->size;
7361 /* while (pos < big1->size) {
7362 successor->bigdigits[pos] = big1->bigdigits[pos];
7363 pos++;
7364 } ** while */
7365 } /* if */
7366 if (IS_NEGATIVE(successor->bigdigits[pos - 1])) {
7367 if (!IS_NEGATIVE(big1->bigdigits[pos - 1])) {
7368 REALLOC_BIG_CHECK_SIZE(resized_successor, successor, pos, pos + 1);
7369 if (unlikely(resized_successor == NULL)) {
7370 FREE_BIG(successor, pos);
7371 raise_error(MEMORY_ERROR);
7372 successor = NULL;
7373 } else {
7374 successor = resized_successor;
7375 COUNT3_BIG(pos, pos + 1);
7376 successor->size++;
7377 successor->bigdigits[pos] = 0;
7378 } /* if */
7379 } else if (successor->bigdigits[pos - 1] == BIGDIGIT_MASK &&
7380 pos >= 2 && IS_NEGATIVE(successor->bigdigits[pos - 2])) {
7381 /* Avoid a MEMORY_ERROR in the strange case */
7382 /* if a 'realloc' which shrinks memory fails. */
7383 REALLOC_BIG_SIZE_OK(resized_successor, successor, pos, pos - 1);
7384 if (likely(resized_successor != NULL)) {
7385 successor = resized_successor;
7386 } /* if */
7387 COUNT3_BIG(pos, pos - 1);
7388 successor->size--;
7389 } /* if */
7390 } /* if */
7391 } /* if */
7392 logFunction(printf("bigSucc --> %s\n", bigHexCStri(successor)););
7393 return successor;
7394 } /* bigSucc */
7395
7396
7397
7398 /**
7399 * Successor of a 'bigInteger' number.
7400 * Big1 is assumed to be a temporary value which is reused.
7401 * @return big1 + 1 .
7402 */
bigSuccTemp(bigIntType big1)7403 bigIntType bigSuccTemp (bigIntType big1)
7404
7405 {
7406 memSizeType pos = 0;
7407 boolType negative;
7408 bigIntType resized_big1;
7409
7410 /* bigSuccTemp */
7411 logFunction(printf("bigSuccTemp(%s)\n", bigHexCStri(big1)););
7412 negative = IS_NEGATIVE(big1->bigdigits[big1->size - 1]);
7413 if (big1->bigdigits[pos] == BIGDIGIT_MASK) {
7414 if (big1->size == 1) {
7415 big1->bigdigits[pos] = 0;
7416 pos++;
7417 } else {
7418 do {
7419 big1->bigdigits[pos] = 0;
7420 pos++;
7421 } while (big1->bigdigits[pos] == BIGDIGIT_MASK);
7422 /* memset(big1->bigdigits, 0, pos * sizeof(bigDigitType)); */
7423 } /* if */
7424 } /* if */
7425 if (pos < big1->size) {
7426 big1->bigdigits[pos]++;
7427 } /* if */
7428 pos = big1->size;
7429 if (IS_NEGATIVE(big1->bigdigits[pos - 1])) {
7430 if (!negative) {
7431 REALLOC_BIG_CHECK_SIZE(resized_big1, big1, pos, pos + 1);
7432 if (unlikely(resized_big1 == NULL)) {
7433 FREE_BIG(big1, big1->size);
7434 raise_error(MEMORY_ERROR);
7435 big1 = NULL;
7436 } else {
7437 big1 = resized_big1;
7438 COUNT3_BIG(pos, pos + 1);
7439 big1->size++;
7440 big1->bigdigits[pos] = 0;
7441 } /* if */
7442 } else if (big1->bigdigits[pos - 1] == BIGDIGIT_MASK &&
7443 pos >= 2 && IS_NEGATIVE(big1->bigdigits[pos - 2])) {
7444 REALLOC_BIG_SIZE_OK(resized_big1, big1, pos, pos - 1);
7445 /* Avoid a MEMORY_ERROR in the strange case */
7446 /* if a 'realloc' which shrinks memory fails. */
7447 if (likely(resized_big1 != NULL)) {
7448 big1 = resized_big1;
7449 } /* if */
7450 COUNT3_BIG(pos, pos - 1);
7451 big1->size--;
7452 } /* if */
7453 } /* if */
7454 logFunction(printf("bigSuccTemp --> %s\n", bigHexCStri(big1)););
7455 return big1;
7456 } /* bigSuccTemp */
7457
7458
7459
7460 /**
7461 * Convert a 'bigInteger' into a big-endian 'bstring'.
7462 * The result uses binary representation with a base of 256.
7463 * @param big1 BigInteger number to be converted.
7464 * @param isSigned Determines the signedness of the result.
7465 * If 'isSigned' is TRUE the result is encoded with the
7466 * twos-complement representation. In this case a negative
7467 * 'big1' is converted to a result where the most significant
7468 * byte (the first byte) has an ordinal > BYTE_MAX (=127).
7469 * @return a bstring with the big-endian representation.
7470 * @exception RANGE_ERROR If 'big1' is negative and 'isSigned' is FALSE.
7471 * @exception MEMORY_ERROR Not enough memory to represent the result.
7472 */
bigToBStriBe(const const_bigIntType big1,const boolType isSigned)7473 bstriType bigToBStriBe (const const_bigIntType big1, const boolType isSigned)
7474
7475 {
7476 memSizeType pos;
7477 int byteNum;
7478 bigDigitType digit;
7479 memSizeType charIndex;
7480 memSizeType result_size;
7481 bstriType result;
7482
7483 /* bigToBStriBe */
7484 logFunction(printf("bigToBStriBe(%s, %d)\n", bigHexCStri(big1), isSigned););
7485 /* The expression computing result_size does not overflow */
7486 /* because the number of bytes in a bigInteger fits in memSizeType. */
7487 result_size = big1->size * (BIGDIGIT_SIZE >> 3);
7488 pos = big1->size - 1;
7489 digit = big1->bigdigits[pos];
7490 byteNum = (BIGDIGIT_SIZE >> 3) - 1;
7491 if (isSigned) {
7492 if (IS_NEGATIVE(digit)) {
7493 while (byteNum > 0 && (digit >> byteNum * CHAR_BIT & 0xFF) == UBYTE_MAX) {
7494 result_size--;
7495 byteNum--;
7496 } /* while */
7497 if (byteNum < 3 && (digit >> byteNum * CHAR_BIT & 0xFF) <= BYTE_MAX) {
7498 result_size++;
7499 byteNum++;
7500 } /* if */
7501 } else {
7502 while (byteNum > 0 && (digit >> byteNum * CHAR_BIT & 0xFF) == 0) {
7503 result_size--;
7504 byteNum--;
7505 } /* while */
7506 if (byteNum < 3 && (digit >> byteNum * CHAR_BIT & 0xFF) > BYTE_MAX) {
7507 result_size++;
7508 byteNum++;
7509 } /* if */
7510 } /* if */
7511 } else {
7512 if (unlikely(IS_NEGATIVE(digit))) {
7513 logError(printf("bigToBStriBe(%s, %d): "
7514 "Number is negative and 'isSigned' is FALSE.\n",
7515 bigHexCStri(big1), isSigned););
7516 raise_error(RANGE_ERROR);
7517 return NULL;
7518 } else {
7519 if (digit == 0 && pos > 0) {
7520 result_size -= (BIGDIGIT_SIZE >> 3);
7521 pos--;
7522 digit = big1->bigdigits[pos];
7523 } /* if */
7524 while (byteNum > 0 && (digit >> byteNum * CHAR_BIT & 0xFF) == 0) {
7525 result_size--;
7526 byteNum--;
7527 } /* while */
7528 } /* if */
7529 } /* if */
7530 if (unlikely(!ALLOC_BSTRI_CHECK_SIZE(result, result_size))) {
7531 raise_error(MEMORY_ERROR);
7532 } else {
7533 result->size = result_size;
7534 charIndex = 0;
7535 for (; byteNum >= 0; byteNum--) {
7536 result->mem[charIndex] = (ucharType) (digit >> byteNum * CHAR_BIT & 0xFF);
7537 charIndex++;
7538 } /* for */
7539 while (pos > 0) {
7540 pos--;
7541 digit = big1->bigdigits[pos];
7542 for (byteNum = (BIGDIGIT_SIZE >> 3) - 1; byteNum >= 0; byteNum--) {
7543 result->mem[charIndex] = (ucharType) (digit >> byteNum * CHAR_BIT & 0xFF);
7544 charIndex++;
7545 } /* for */
7546 } /* while */
7547 } /* if */
7548 logFunction(printf("bigToBStriBe --> \"%s\"\n",
7549 bstriAsUnquotedCStri(result)););
7550 return result;
7551 } /* bigToBStriBe */
7552
7553
7554
7555 /**
7556 * Convert a 'bigInteger' into a little-endian 'bstring'.
7557 * The result uses binary representation with a base of 256.
7558 * @param big1 BigInteger number to be converted.
7559 * @param isSigned Determines the signedness of the result.
7560 * If 'isSigned' is TRUE the result is encoded with the
7561 * twos-complement representation. In this case a negative
7562 * 'big1' is converted to a result where the most significant
7563 * byte (the last byte) has an ordinal > BYTE_MAX (=127).
7564 * @return a bstring with the little-endian representation.
7565 * @exception RANGE_ERROR If 'big1' is negative and 'isSigned' is FALSE.
7566 * @exception MEMORY_ERROR Not enough memory to represent the result.
7567 */
bigToBStriLe(const const_bigIntType big1,const boolType isSigned)7568 bstriType bigToBStriLe (const const_bigIntType big1, const boolType isSigned)
7569
7570 {
7571 memSizeType pos;
7572 int byteNum;
7573 bigDigitType digit;
7574 memSizeType charIndex;
7575 memSizeType result_size;
7576 bstriType result;
7577
7578 /* bigToBStriLe */
7579 logFunction(printf("bigToBStriLe(%s, %d)\n", bigHexCStri(big1), isSigned););
7580 /* The expression computing result_size does not overflow */
7581 /* because the number of bytes in a bigInteger fits in memSizeType. */
7582 result_size = big1->size * (BIGDIGIT_SIZE >> 3);
7583 pos = big1->size - 1;
7584 digit = big1->bigdigits[pos];
7585 byteNum = (BIGDIGIT_SIZE >> 3) - 1;
7586 if (isSigned) {
7587 if (IS_NEGATIVE(digit)) {
7588 while (byteNum > 0 && (digit >> byteNum * CHAR_BIT & 0xFF) == UBYTE_MAX) {
7589 result_size--;
7590 byteNum--;
7591 } /* while */
7592 if (byteNum < 3 && (digit >> byteNum * CHAR_BIT & 0xFF) <= BYTE_MAX) {
7593 result_size++;
7594 byteNum++;
7595 } /* if */
7596 } else {
7597 while (byteNum > 0 && (digit >> byteNum * CHAR_BIT & 0xFF) == 0) {
7598 result_size--;
7599 byteNum--;
7600 } /* while */
7601 if (byteNum < 3 && (digit >> byteNum * CHAR_BIT & 0xFF) > BYTE_MAX) {
7602 result_size++;
7603 byteNum++;
7604 } /* if */
7605 } /* if */
7606 } else {
7607 if (unlikely(IS_NEGATIVE(digit))) {
7608 logError(printf("bigToBStriLe(%s, %d): "
7609 "Number is negative and 'isSigned' is FALSE.\n",
7610 bigHexCStri(big1), isSigned););
7611 raise_error(RANGE_ERROR);
7612 return NULL;
7613 } else {
7614 if (digit == 0 && pos > 0) {
7615 result_size -= (BIGDIGIT_SIZE >> 3);
7616 pos--;
7617 digit = big1->bigdigits[pos];
7618 } /* if */
7619 while (byteNum > 0 && (digit >> byteNum * CHAR_BIT & 0xFF) == 0) {
7620 result_size--;
7621 byteNum--;
7622 } /* while */
7623 } /* if */
7624 } /* if */
7625 if (unlikely(!ALLOC_BSTRI_CHECK_SIZE(result, result_size))) {
7626 raise_error(MEMORY_ERROR);
7627 } else {
7628 result->size = result_size;
7629 charIndex = result_size - 1;
7630 for (; byteNum >= 0; byteNum--) {
7631 result->mem[charIndex] = (ucharType) (digit >> byteNum * CHAR_BIT & 0xFF);
7632 charIndex--;
7633 } /* for */
7634 while (pos > 0) {
7635 pos--;
7636 digit = big1->bigdigits[pos];
7637 for (byteNum = (BIGDIGIT_SIZE >> 3) - 1; byteNum >= 0; byteNum--) {
7638 result->mem[charIndex] = (ucharType) (digit >> byteNum * CHAR_BIT & 0xFF);
7639 charIndex--;
7640 } /* for */
7641 } /* while */
7642 } /* if */
7643 logFunction(printf("bigToBStriLe -->\"%s\"\n",
7644 bstriAsUnquotedCStri(result)););
7645 return result;
7646 } /* bigToBStriLe */
7647
7648
7649
7650 /**
7651 * Convert a 'bigInteger' to an 'int16Type' number.
7652 * @return the int16Type result of the conversion.
7653 * @param err_info Unchanged if the function succeeds or
7654 * RANGE_ERROR The number is too small or too big
7655 * to fit into a int16Type value.
7656 */
bigToInt16(const const_bigIntType big1,errInfoType * err_info)7657 int16Type bigToInt16 (const const_bigIntType big1, errInfoType *err_info)
7658
7659 {
7660 memSizeType pos;
7661 int32Type result;
7662
7663 /* bigToInt16 */
7664 logFunction(printf("bigToInt16(%s)\n", bigHexCStri(big1)););
7665 #if BIGDIGIT_SIZE > 16
7666 if (unlikely(big1->size > 1)) {
7667 #else
7668 if (unlikely(big1->size > sizeof(int16Type) / (BIGDIGIT_SIZE >> 3))) {
7669 #endif
7670 logError(printf("bigToInt16(%s): Number too big or too small.\n",
7671 bigHexCStri(big1)););
7672 *err_info = RANGE_ERROR;
7673 result = 0;
7674 } else {
7675 pos = big1->size - 1;
7676 result = (int32Type) (signedBigDigitType) big1->bigdigits[pos];
7677 #if BIGDIGIT_SIZE > 16
7678 if (unlikely(result < INT16TYPE_MIN || result > INT16TYPE_MAX)) {
7679 logError(printf("bigToInt16(%s): Number too big or too small.\n",
7680 bigHexCStri(big1)););
7681 *err_info = RANGE_ERROR;
7682 result = 0;
7683 } /* if */
7684 #elif BIGDIGIT_SIZE < 16
7685 while (pos > 0) {
7686 pos--;
7687 result <<= BIGDIGIT_SIZE;
7688 result |= (int16Type) big1->bigdigits[pos];
7689 } /* while */
7690 #endif
7691 } /* if */
7692 logFunction(printf("bigToInt16 --> " FMT_D32 "\n", result););
7693 return (int16Type) result;
7694 } /* bigToInt16 */
7695
7696
7697
7698 /**
7699 * Convert a 'bigInteger' to an 'int32Type' number.
7700 * @return the int32Type result of the conversion.
7701 * @param big1 BigInteger to be converted.
7702 * @param err_info Only used if err_info is not NULL.
7703 * Unchanged if the function succeeds or
7704 * RANGE_ERROR The number is too small or too big
7705 * to fit into a int32Type value.
7706 * @exception RANGE_ERROR If err_info is NULL and the number is
7707 * too small or too big to fit into a int32Type value.
7708 */
7709 int32Type bigToInt32 (const const_bigIntType big1, errInfoType *err_info)
7710
7711 {
7712 memSizeType pos;
7713 int32Type result;
7714
7715 /* bigToInt32 */
7716 logFunction(printf("bigToInt32(%s)\n", bigHexCStri(big1)););
7717 /* Assume that BIGDIGIT_SIZE <= 32 holds. */
7718 if (unlikely(big1->size > sizeof(int32Type) / (BIGDIGIT_SIZE >> 3))) {
7719 logError(printf("bigToInt32(%s): Number too big or too small.\n",
7720 bigHexCStri(big1)););
7721 if (err_info == NULL) {
7722 raise_error(RANGE_ERROR);
7723 } else {
7724 *err_info = RANGE_ERROR;
7725 } /* if */
7726 result = 0;
7727 } else {
7728 pos = big1->size - 1;
7729 result = (int32Type) (signedBigDigitType) big1->bigdigits[pos];
7730 #if BIGDIGIT_SIZE < 32
7731 while (pos > 0) {
7732 pos--;
7733 result <<= BIGDIGIT_SIZE;
7734 result |= (int32Type) big1->bigdigits[pos];
7735 } /* while */
7736 #endif
7737 } /* if */
7738 logFunction(printf("bigToInt32 --> " FMT_D32 "\n", result););
7739 return result;
7740 } /* bigToInt32 */
7741
7742
7743
7744 #ifdef INT64TYPE
7745 /**
7746 * Convert a 'bigInteger' to an 'int64Type' number.
7747 * @return the int64Type result of the conversion.
7748 * @param big1 BigInteger to be converted.
7749 * @param err_info Only used if err_info is not NULL.
7750 * Unchanged if the function succeeds or
7751 * RANGE_ERROR The number is too small or too big
7752 * to fit into a int64Type value.
7753 * @exception RANGE_ERROR If err_info is NULL and the number is
7754 * too small or too big to fit into a int64Type value.
7755 */
7756 int64Type bigToInt64 (const const_bigIntType big1, errInfoType *err_info)
7757
7758 {
7759 memSizeType pos;
7760 int64Type result;
7761
7762 /* bigToInt64 */
7763 logFunction(printf("bigToInt64(%s)\n", bigHexCStri(big1)););
7764 /* Assume that BIGDIGIT_SIZE <= 32 holds. */
7765 if (unlikely(big1->size > sizeof(int64Type) / (BIGDIGIT_SIZE >> 3))) {
7766 logError(printf("bigToInt64(%s): Number too big or too small.\n",
7767 bigHexCStri(big1)););
7768 if (err_info == NULL) {
7769 raise_error(RANGE_ERROR);
7770 } else {
7771 *err_info = RANGE_ERROR;
7772 } /* if */
7773 result = 0;
7774 } else {
7775 pos = big1->size - 1;
7776 result = (int64Type) (signedBigDigitType) big1->bigdigits[pos];
7777 #if BIGDIGIT_SIZE < 64
7778 while (pos > 0) {
7779 pos--;
7780 result <<= BIGDIGIT_SIZE;
7781 result |= (int64Type) big1->bigdigits[pos];
7782 } /* while */
7783 #endif
7784 } /* if */
7785 logFunction(printf("bigToInt64 --> " FMT_D64 "\n", result););
7786 return result;
7787 } /* bigToInt64 */
7788
7789
7790
7791 /**
7792 * Convert a 'bigInteger' to an 'uint64Type' number.
7793 * @return the uint64Type result of the conversion.
7794 * @exception RANGE_ERROR The number is negative or too big to fit
7795 * into a uint64Type value.
7796 */
7797 uint64Type bigToUInt64 (const const_bigIntType big1)
7798
7799 {
7800 memSizeType pos;
7801 uint64Type result;
7802
7803 /* bigToUInt64 */
7804 logFunction(printf("bigToUInt64(%s)\n", bigHexCStri(big1)););
7805 pos = big1->size - 1;
7806 if (unlikely(IS_NEGATIVE(big1->bigdigits[pos]))) {
7807 logError(printf("bigToUInt64(%s): Number is negative.\n",
7808 bigHexCStri(big1)););
7809 raise_error(RANGE_ERROR);
7810 result = 0;
7811 } else {
7812 /* Assume that BIGDIGIT_SIZE <= 32 holds. */
7813 if (big1->bigdigits[pos] == 0 && pos > 0) {
7814 pos--;
7815 } /* if */
7816 if (unlikely(pos >= sizeof(uint64Type) / (BIGDIGIT_SIZE >> 3))) {
7817 logError(printf("bigToUInt64(%s): Number too big.\n",
7818 bigHexCStri(big1)););
7819 raise_error(RANGE_ERROR);
7820 result = 0;
7821 } else {
7822 result = (uint64Type) big1->bigdigits[pos];
7823 #if BIGDIGIT_SIZE < 64
7824 while (pos > 0) {
7825 pos--;
7826 result <<= BIGDIGIT_SIZE;
7827 result |= (uint64Type) big1->bigdigits[pos];
7828 } /* while */
7829 #endif
7830 } /* if */
7831 } /* if */
7832 logFunction(printf("bigToUInt64(%s) --> " FMT_U64 "\n",
7833 bigHexCStri(big1), result););
7834 return result;
7835 } /* bigToUInt64 */
7836 #endif
7837
7838
7839
7840 bigIntType bigXor (const_bigIntType big1, const_bigIntType big2)
7841
7842 {
7843 const_bigIntType help_big;
7844 memSizeType pos;
7845 bigDigitType big2_sign;
7846 bigIntType result;
7847
7848 /* bigXor */
7849 logFunction(printf("bigXor(%s,", bigHexCStri(big1));
7850 printf("%s)\n", bigHexCStri(big2)););
7851 if (big2->size > big1->size) {
7852 help_big = big1;
7853 big1 = big2;
7854 big2 = help_big;
7855 } /* if */
7856 if (unlikely(!ALLOC_BIG_SIZE_OK(result, big1->size))) {
7857 raise_error(MEMORY_ERROR);
7858 } else {
7859 pos = 0;
7860 do {
7861 result->bigdigits[pos] = big1->bigdigits[pos] ^ big2->bigdigits[pos];
7862 pos++;
7863 } while (pos < big2->size);
7864 big2_sign = IS_NEGATIVE(big2->bigdigits[pos - 1]) ? BIGDIGIT_MASK : 0;
7865 for (; pos < big1->size; pos++) {
7866 result->bigdigits[pos] = big1->bigdigits[pos] ^ big2_sign;
7867 } /* for */
7868 result->size = pos;
7869 result = normalize(result);
7870 } /* if */
7871 logFunction(printf("bigXor --> %s\n", bigHexCStri(result)););
7872 return result;
7873 } /* bigXor */
7874
7875
7876
7877 bigIntType bigZero (void)
7878
7879 {
7880 bigIntType result;
7881
7882 /* bigZero */
7883 if (unlikely(!ALLOC_BIG_SIZE_OK(result, 1))) {
7884 raise_error(MEMORY_ERROR);
7885 } else {
7886 result->size = 1;
7887 result->bigdigits[0] = 0;
7888 } /* if */
7889 return result;
7890 } /* bigZero */
7891
7892 #endif
7893