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