Bug Summary

File:subcmd/unitools/bigint.c
Warning:line 2242, column 20
The result of left shift is undefined because the right operand is >= 32, not smaller than 32, the capacity of 'BIntS'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name bigint.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/kfp/aldor/aldor/aldor/subcmd/unitools -fcoverage-compilation-dir=/home/kfp/aldor/aldor/aldor/subcmd/unitools -resource-dir /usr/local/lib/clang/18 -D PACKAGE_NAME="aldor" -D PACKAGE_TARNAME="aldor" -D PACKAGE_VERSION="1.4.0" -D PACKAGE_STRING="aldor 1.4.0" -D PACKAGE_BUGREPORT="aldor@xinutec.org" -D PACKAGE_URL="" -D PACKAGE="aldor" -D VERSION="1.4.0" -D YYTEXT_POINTER=1 -D HAVE_STDIO_H=1 -D HAVE_STDLIB_H=1 -D HAVE_STRING_H=1 -D HAVE_INTTYPES_H=1 -D HAVE_STDINT_H=1 -D HAVE_STRINGS_H=1 -D HAVE_SYS_STAT_H=1 -D HAVE_SYS_TYPES_H=1 -D HAVE_UNISTD_H=1 -D STDC_HEADERS=1 -D HAVE_LIBREADLINE=1 -D HAVE_READLINE_READLINE_H=1 -D HAVE_READLINE_HISTORY=1 -D HAVE_READLINE_HISTORY_H=1 -D USE_GLOOP_SHELL=1 -D GENERATOR_COROUTINES=0 -D HAVE_DLFCN_H=1 -D LT_OBJDIR=".libs/" -I . -I ./../../src -I ../../src -internal-isystem /usr/local/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2026-01-15-223856-845667-1 -x c bigint.c
1/*****************************************************************************
2 *
3 * bigint.c: Big integer arithmetic.
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ****************************************************************************/
8
9/*
10 * Operations of the form "bintAaaa" do not modify their arguments,
11 * and always allocate new values as their results. E.g., the statement
12 *
13 * b1 = bintShift(b0, i);
14 *
15 * causes the BInt value b0 to be shifted by i bits, creating
16 * a new BInt value b1.
17 * These operations work on normalized numbers.
18 * I.e. When a number is small enough, it is represented immediately.
19 * Otherwise it is stored and Placec(b) > 0 && Placev(b)[Placec(b)-1] != 0.
20 *
21 * Operations of the form "xintAaaa" can modify their arguments or,
22 * if necessary, reallocate and free their input.
23 *
24 * Operations of the form "iintAaaa" do no storage allocation whatsoever
25 * and perform the big integer arithmetic algorithms.
26 */
27
28#include "axlgen.h"
29#include "bigint.h"
30#include "debug.h"
31#include "store.h"
32#include "util.h"
33#include "compopt.h"
34
35/*
36 * The following symbols are used to conditionalize code in this file:
37 *
38 * BIGINT_DO_DEBUG -- Turns on DEBUG(bint) blocks.
39 * BIGINT_DEBUG_IMMED -- Turns on (bad) code for generalized ImmedIfCan.
40 * BIGINT_SHORT_IMMED -- Defines IInt as "short" rather than "int".
41 * BIGINT_USE_WHOLE_WORDS -- Turns on (incomplete) code for long bint digits.
42 * BIGINT_SHHH -- Turns off all debugging code.
43 *
44 */
45
46
47/*
48 * Define BIGINT_DO_DEBUG to display debug info.
49 */
50#ifdef BIGINT_DO_DEBUG
51# define bintDebug((int) 0) true1
52#else
53# define bintDebug((int) 0) false((int) 0)
54#endif
55
56#define bintDEBUGif (!((int) 0)) { } else fprintf DEBUG_IF(bint)if (!((int) 0)) { } else fprintf
57
58#ifdef FOAM_RTS
59# define dbOut stdoutstdout
60#endif
61
62/*****************************************************************************
63 *
64 * :: Remove linkage to String (and hence format.c etc)
65 *
66 ****************************************************************************/
67
68localstatic String
69localStrAlloc(Length n)
70{
71 String s;
72 s = (String) stoAlloc((unsigned) OB_String7, n + 1);
73 s[0] = 0;
74 s[n] = 0;
75 return s;
76}
77
78localstatic void
79localStrFree(String s)
80{
81 stoFree((Pointer) s);
82}
83
84/*****************************************************************************
85 *
86 * :: Integer range defintitions
87 *
88 * Should work for 2's complement n-bit ints, for even n >= 4.
89 *
90 *****************************************************************************/
91
92
93#ifdef BIGINT_SHORT_IMMED
94typedef short IInt;
95typedef UShort UIInt;
96#else
97typedef long IInt;
98typedef unsigned long UIInt;
99#endif
100
101
102/*
103 * Conversion between ints and immediate BInts.
104 */
105#define IsImmed(b)((long)(b) & 1) ((long)(b) & 1)
106#define MkImmed(n)((((long)(n)) << 1) | 1) ((((long)(n)) << 1) | 1)
107#define UnImmed(n)((n) >> 1) ((n) >> 1)
108
109#define BIntToInt(b)((IInt) ((((long) (b))) >> 1)) ((IInt) UnImmed(ptrToLong(b))((((long) (b))) >> 1))
110#define IntToBInt(n)((BInt) ((Pointer)(((((long)(n)) << 1) | 1)))) ((BInt) ptrFrLong(MkImmed(n))((Pointer)(((((long)(n)) << 1) | 1))))
111#define BIntZero((BInt) ((((long)(0)) << 1) | 1)) ((BInt) MkImmed(0)((((long)(0)) << 1) | 1))
112#define BIntOne((BInt) ((((long)(1)) << 1) | 1)) ((BInt) MkImmed(1)((((long)(1)) << 1) | 1))
113
114/*
115 * Fields of stored BInts.
116 */
117#define Beq(a,b)((a) == (b)) ((a) == (b))
118#define IsNeg(b)((b)->isNeg) ((b)->isNeg)
119#define Placec(b)((b)->placec) ((b)->placec)
120#define Placea(b)((b)->placea) ((b)->placea)
121#define Placev(b)((b)->placev) ((b)->placev)
122
123/*
124 * The minimum and maximum values of type int.
125 */
126#ifndef INT_MIN(-2147483647 -1)
127# define INT_MIN(-2147483647 -1) ((IInt) ((-1)<<(bitsizeof(IInt)(8 * sizeof(IInt))-1)))
128# define INT_MAX2147483647 (- (INT_MIN(-2147483647 -1) + 1)) /* 2's complement */
129#endif
130
131/*
132 * These are the min + max int values which are represented as immediate BInts.
133 * These must satisfy BIntToInt(IntToBInt(n)) == n,
134 * hence the "-2" in INT_MIN_IMMED.
135 */
136#define INT_LG_IMMED((8 * sizeof(IInt))-2) (bitsizeof(IInt)(8 * sizeof(IInt))-2)
137#define INT_MIN_IMMED((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1) ((((IInt) 3) << INT_LG_IMMED((8 * sizeof(IInt))-2)) + 1)
138#define INT_MAX_IMMED(- (long) ((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1)) (- (long) INT_MIN_IMMED((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1))
139#define INT_IS_IMMED(n)(((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1)<= (long
)(n) && (long)(n)<= (- (long) ((((IInt) 3) <<
((8 * sizeof(IInt))-2)) + 1)))
(INT_MIN_IMMED((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1)<= (long)(n) && (long)(n)<= INT_MAX_IMMED(- (long) ((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1)))
140
141#define INT_LG_HALF(((8 * sizeof(IInt))-2)/2) ((bitsizeof(IInt)(8 * sizeof(IInt))-2)/2)
142#define INT_MAX_HALF((((IInt) 1)<<((((8 * sizeof(IInt))-2)/2))) -1) ((((IInt) 1)<<(INT_LG_HALF(((8 * sizeof(IInt))-2)/2))) -1)
143#define INT_MIN_HALF(-((((IInt) 1)<<((((8 * sizeof(IInt))-2)/2))) -1)) (-INT_MAX_HALF((((IInt) 1)<<((((8 * sizeof(IInt))-2)/2))) -1))
144#define INT_IS_HALF(n)((-((((IInt) 1)<<((((8 * sizeof(IInt))-2)/2))) -1)) <=
(long)(n) && (long)(n)<= ((((IInt) 1)<<((((
8 * sizeof(IInt))-2)/2))) -1))
(INT_MIN_HALF(-((((IInt) 1)<<((((8 * sizeof(IInt))-2)/2))) -1)) <= (long)(n) && (long)(n)<= INT_MAX_HALF((((IInt) 1)<<((((8 * sizeof(IInt))-2)/2))) -1))
145
146/*
147 * Calculation radix.
148 * Must be possible to detect overflow on addition and implement double word
149 * multiply and divide.
150 */
151
152#ifdef BIGINT_DO_DEBUG
153# define BINT_LG_RADIX((8 * sizeof(BIntS))) 7
154#else
155# define BINT_LG_RADIX((8 * sizeof(BIntS))) (bitsizeof(BIntS)(8 * sizeof(BIntS)))
156#endif
157#define BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))) (((unsigned long) 1) << BINT_LG_RADIX((8 * sizeof(BIntS))))
158 /* Might not be representable! */
159#define BINT_RADIX_MASK((((unsigned long) 1) << ((8 * sizeof(BIntS)))) - 1) (BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))) - 1)
160#define BINT_RADIX_MINUS_1((((unsigned long) 1) << ((8 * sizeof(BIntS)))) - 1) (BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))) - 1)
161
162/*****************************************************************************
163 *
164 * :: Double precision arithmetic macros
165 *
166 *****************************************************************************/
167
168typedef ULong BIntD; /* To contain two BInt digits. */
169
170#define TestGTDouble(b, h1, l1, h2, l2){ BIntS h1_ = (h1), h2_ = (h2); (b) = (h1_ > h2_) || (h1_ ==
h2_ && (l1)>(l2)); }
{ \
171 BIntS h1_ = (h1), h2_ = (h2); \
172 (b) = (h1_ > h2_) || (h1_ == h2_ && (l1)>(l2)); \
173}
174
175#define TimesDouble(h, l, a, b){ BIntD t_ = (BIntD)(a)*(BIntD)(b); (h) = t_ / (((unsigned long
) 1) << ((8 * sizeof(BIntS)))); (l) = t_ % (((unsigned long
) 1) << ((8 * sizeof(BIntS)))); }
{ \
176 BIntD t_ = (BIntD)(a)*(BIntD)(b); \
177 (h) = t_ / BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))); \
178 (l) = t_ % BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))); \
179}
180
181#define DivideDouble(q, r, nh, nl, d){ BIntD n_ = (BIntD)(nh)*(BIntD)(((unsigned long) 1) <<
((8 * sizeof(BIntS)))) + (nl); BIntD d_ = (d); (q) = n_ / d_
; (r) = n_ % d_; }
{ \
182 BIntD n_ = (BIntD)(nh)*(BIntD)BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))) + (nl);\
183 BIntD d_ = (d); \
184 (q) = n_ / d_; \
185 (r) = n_ % d_; \
186}
187
188#define PlusStep(kout, r, a, b, kin){ BIntD r_ = (BIntD)(a)+(BIntD)(b)+(BIntD)(kin); BIntS k_ = (
r_ >= (BIntD) (((unsigned long) 1) << ((8 * sizeof(BIntS
))))); if (k_) r_ -= (((unsigned long) 1) << ((8 * sizeof
(BIntS)))); (r) = r_; (kout) = k_; }
{ \
189 BIntD r_ = (BIntD)(a)+(BIntD)(b)+(BIntD)(kin);\
190 BIntS k_ = (r_ >= (BIntD) BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS))))); \
191 if (k_) r_ -= BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))); \
192 (r) = r_; \
193 (kout) = k_; \
194}
195
196#define MinusStep(kp1out, r, a, b, kp1in){ BIntD r_ = (BIntD)(a)+(BIntD)((((((unsigned long) 1) <<
((8 * sizeof(BIntS)))) - 1) - (b)))+(BIntD)(kp1in); BIntS k_
= (r_ >= (BIntD) (((unsigned long) 1) << ((8 * sizeof
(BIntS))))); if (k_) r_ -= (((unsigned long) 1) << ((8 *
sizeof(BIntS)))); (r) = r_; (kp1out) = k_; }
\
197 PlusStep(kp1out, r, a, (BINT_RADIX_MINUS_1 - (b)), kp1in){ BIntD r_ = (BIntD)(a)+(BIntD)((((((unsigned long) 1) <<
((8 * sizeof(BIntS)))) - 1) - (b)))+(BIntD)(kp1in); BIntS k_
= (r_ >= (BIntD) (((unsigned long) 1) << ((8 * sizeof
(BIntS))))); if (k_) r_ -= (((unsigned long) 1) << ((8 *
sizeof(BIntS)))); (r) = r_; (kp1out) = k_; }
198
199#define TimesStep(kout, r, a, b, c, kin){ BIntD t_ = (BIntD)(a)*(BIntD)(b)+(BIntD)(c)+(BIntD)(kin); (
r) = t_ % (((unsigned long) 1) << ((8 * sizeof(BIntS)))
); (kout) = t_ / (((unsigned long) 1) << ((8 * sizeof(BIntS
)))); }
{ \
200 BIntD t_ = (BIntD)(a)*(BIntD)(b)+(BIntD)(c)+(BIntD)(kin); \
201 (r) = t_ % BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))); \
202 (kout) = t_ / BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))); \
203}
204
205
206
207/*****************************************************************************
208 *
209 * :: Related machine integer operations
210 *
211 *****************************************************************************/
212
213/*
214 * The length of n, in bits. I.e. cieling(lg(abs(n))).
215 * Define the bit length of zero to be one bit.
216 */
217Length
218uintLength(unsigned long u)
219{
220 register Length i;
221 register UIInt p;
222
223 /* Eventually the unsigned quantity p is bigger than u = abs(n). */
224 /* At each stage of the loop, any u < p can fit in i bits. */
225 for (i = 1, p = 2; ; i += 1, p <<= 1)
226 if (!p || u < p) break;
227 return i;
228}
229
230Length
231intLength(long n)
232{
233 return uintLength((n < 0) ? -n : n);
234}
235
236
237Bool
238uintBit(unsigned long si, Length ix)
239{
240 return (ix < bitsizeof(UIInt)(8 * sizeof(UIInt))) && ( ((ULong)si) & (1L<<ix)) != 0;
241}
242
243Bool
244intBit(long si, Length ix)
245{
246 return uintBit((si < 0) ? -si : si, ix);
247}
248
249/****************************************************************************
250 *
251 * :: Input/output
252 *
253 ****************************************************************************/
254
255int
256bintPrint(FILE *fout, BInt b)
257{
258 int cc;
259 String s;
260
261 if (IsImmed(b)((long)(b) & 1)) return fprintf(fout, "%ld", BIntToInt(b)((IInt) ((((long) (b))) >> 1)));
262
263 s = bintToString(b);
264 cc = fprintf(fout, "%s", s);
265 localStrFree(s);
266
267 return cc;
268}
269
270void
271bintPrintDb(BInt b)
272{
273 bintPrint(dbOut, b);
274 fprintf(dbOut, "\n");
275}
276
277int
278bintPrint16(FILE *fout, BInt b)
279{
280 int i, cc;
281
282 if (IsImmed(b)((long)(b) & 1)) return fprintf(fout, "0x%lx", BIntToInt(b)((IInt) ((((long) (b))) >> 1)));
283
284 cc = fprintf(fout, IsNeg(b)((b)->isNeg) ? "-" : "+");
285 cc += fprintf(fout, "0x");
286
287 for (i = Placec(b)((b)->placec) - 1; i >= 0; i--)
288 cc += fprintf(fout, "%0*x.",
289 (int) QUO_ROUND_UP(BINT_LG_RADIX,4)((((8 * sizeof(BIntS)))) % (4) ? (((8 * sizeof(BIntS))))/(4) +
1 : (((8 * sizeof(BIntS))))/(4))
,
290 Placev(b)((b)->placev)[i]);
291
292 return cc;
293}
294
295/*
296 * +0b[3/4]10,10100,00110.
297 *
298 * [3/4] -- 3 of 4 allocated places are used
299 */
300
301int
302bintPrint2(FILE *fout, BInt b)
303{
304 int i, n, cc = 0;
305
306 if (bintIsNeg(b)) cc += fprintf(fout, "-");
307
308 cc += fprintf(fout, "0b");
309
310 if (IsImmed(b)((long)(b) & 1))
311 cc += fprintf(fout, "[0/0]");
312 else
313 cc += fprintf(fout, "[%d/%d]", (int) Placec(b)((b)->placec), (int) Placea(b)((b)->placea));
314
315 n = bintLength(b);
316
317 for (i = n-1; i >= 0; i--)
318 cc += fprintf(fout, bintBit(b, i) ? "1" : "0");
319
320 return cc;
321}
322
323/*
324 * Overestimate the size of a base 10 string representation for b,
325 * by dividing by 3 (not log(10)/log(2) > 3.32).
326 * +3 for signs, \0, etc.
327 * +dio for temp leading zeros.
328 */
329
330int
331bintStringSize(BInt b)
332{
333 IInt dio;
334 ULong rio;
335
336 if (IsImmed(b)((long)(b) & 1)) return INT_LG_IMMED((8 * sizeof(IInt))-2);
337
338 /*
339 * Determine power of output radix for divisions.
340 * This is the largest power of 10 < BINT_RADIX.
341 */
342 for (rio = 10, dio = 1; 10*rio <= BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))); rio *= 10, dio++)
343 ;
344 return bintLength(b)/3+3+dio;
345}
346
347
348/*
349 * Compute a base 10 string representation of b.
350 * The string representation includes a terminating \0 character.
351 */
352String
353bintIntoString(String s, BInt b)
354{
355 Bool isNeg;
356 IInt digEst, i, j, dio;
357 ULong rio;
358 BIntS r;
359
360 if (IsImmed(b)((long)(b) & 1)) {
361 sprintf(s, "%ld", BIntToInt(b)((IInt) ((((long) (b))) >> 1)));
362 return s;
363 }
364
365 /*
366 * Determine power of output radix for divisions.
367 * This is the largest power of 10 < BINT_RADIX.
368 */
369 for (rio = 10, dio = 1; 10*rio <= BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))); rio *= 10, dio++)
370 ;
371
372 /*
373 * Make copy for in-place divisions.
374 */
375 b = bintCopy(b);
376 isNeg = IsNeg(b)((b)->isNeg);
377
378 digEst = bintStringSize(b);
379 i = digEst;
380 s[--i] = 0;
381
382 while (Placec(b)((b)->placec) > 0) {
383 iintDivideS(b, &r, b, (BIntS) rio);
384 for (j = 0; j < dio; j++) {
385 s[--i] = '0' + r % 10;
386 r /= 10;
387 }
388 }
389
390 while (s[i] == '0') i++; /* Cd have leading zeros. */
391 if (s[i] == 0) s[--i] = '0'; /* Ensure at least one digit. */
392 if (isNeg) s[--i] = '-'; /* Put on sign. */
393
394 /*
395 * Move text to the beginning of the string.
396 */
397 assert(i >= 0)do { if (!(i >= 0)) _do_assert(("i >= 0"),"bigint.c",397
); } while (0)
;
398 if (i > 0) for (j = 0; i < digEst; i++, j++) s[j] = s[i];
399
400 bintFree(b);
401
402 return s;
403}
404
405
406/*
407 * Compute a base 10 string representation of b.
408 * The string representation includes a terminating \0 character.
409 */
410String
411bintToString(BInt b)
412{
413 IInt digEst = bintStringSize(b);
414 String s = localStrAlloc(digEst);
415
416 bintIntoString(s, b);
417
418 return s;
419}
420
421/*
422 * Convert from the textual representation of an Aldor number into a big
423 * integer. This function may be invoked (indirectly) by convert()$Machine
424 * and cannot assume base 10.
425 *
426 * General Aldor integer format is RRrWW
427 *
428 * RR is the radix part (2-36)
429 * 'r' is the radix character.
430 * WW is the whole part ([0-9A-Z]+).
431 */
432BInt
433bintFrString(String s)
434{
435 return bintRadixScanFrString(s, NULL((void*)0));
436}
437
438#define fiRadixChar('r') ('r')
439#define fiPlusChar('+') ('+')
440#define fiMinusChar('-') ('-')
441
442/* Scan a big integer with possible radix specification */
443BInt
444bintRadixScanFrString(String num, String *pEnd)
445{
446 Bool isNeg = false((int) 0);
447 String rpos = (String)NULL((void*)0);
448 String end;
449 long radix = 10;
450 BInt retval;
451 Length rlen, ndigs, bpd;
452 IInt dim, dio;
453 UIInt ires;
454 IInt l, l0, n;
455 ULong rim, rio, nbits;
456 ULong maxi;
457
458
459 /* Skip over leading whitespace */
460 while (isspace(*num)((*__ctype_b_loc ())[(int) ((*num))] & (unsigned short int
) _ISspace)
)
461 num++;
462
463
464 /* Deal with the sign (if any) */
465 if ((*num == fiPlusChar('+')) || (*num == fiMinusChar('-')))
466 {
467 isNeg = (*num == fiMinusChar('-')) ? true1 : false((int) 0);
468 num++;
469 }
470
471
472 /*
473 * Locate the end of the string: start by skipping over
474 * the leading part (which must be in base 10). This
475 * might be the radix or it might be the whole part.
476 */
477 for (end = num; isdigit(*end)((*__ctype_b_loc ())[(int) ((*end))] & (unsigned short int
) _ISdigit)
; end++);
478
479
480 /* Is there a radix marker? */
481 if (*end == fiRadixChar('r'))
482 {
483 /* Yes - note its position */
484 rpos = end;
485 end++;
486
487
488 /* Skip past the whole part */
489 for (;isdigit(*end)((*__ctype_b_loc ())[(int) ((*end))] & (unsigned short int
) _ISdigit)
|| isupper(*end)((*__ctype_b_loc ())[(int) ((*end))] & (unsigned short int
) _ISupper)
;end++);
490 }
491 else
492 {
493 /* NOOOOOOOOOOOOOOO!!!!!!!!!!!!!! */
494 /* Skip past the decimal whole part */
495 for (;isdigit(*end)((*__ctype_b_loc ())[(int) ((*end))] & (unsigned short int
) _ISdigit)
;end++);
496 }
497
498
499 /* Did the caller want to know where the number ends? */
500 if (pEnd) *pEnd = end;
501
502
503 /* There must be something before the radix marker */
504 if (rpos == num)
505 return IntToBInt((long) 0)((BInt) ((Pointer)(((((long)((long) 0)) << 1) | 1)))); /* Bad number */
506
507
508 /* Extract the radix (if any) */
509 if (rpos)
510 {
511 /* Extract the radix as a (small) decimal integer */
512 rlen = rpos - num;
513 radix = ulongSmallIntFrString(num, rlen, 10);
514
515
516 /* Valid radix: 2-36 inclusive */
517 if (errno(*__errno_location ()) || (radix < 2) || (radix > 36))
518 return IntToBInt((long) 0)((BInt) ((Pointer)(((((long)((long) 0)) << 1) | 1))));
519
520
521 /* Move to the start of the whole part */
522 num = rpos + 1;
523 }
524
525
526 /*
527 * Determine the largest power `rim' of the input radix that
528 * can be used for immediate representation. We want `rim' such
529 * that (INT_MAX_IMMED/radix < rim <= INT_MAX_IMMED). We can
530 * not check whether (radix*rim <= INT_MAX_IMMED) because the
531 * LHS may overflow for large `radix'. Instead we `rim' such
532 * that (INT_MAX_IMMED/(radix^2) < rim <= INT_MAX_IMMED/radix).
533 * This means that for all radix, (radix*rim <= INT_MAX_IMMED).
534 */
535 maxi = INT_MAX_IMMED(- (long) ((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1)) / radix;
536 for (
537 rim = radix, dim = 1;
538 radix*rim <= maxi;
539 rim *= radix, dim++
540 );
541
542
543 /* Now satisfy (INT_MAX_IMMED/radix < rim <= INT_MAX_IMMED) */
544 rim *= radix, dim++;
545
546
547 /*
548 * Determine the largest power `rio' of input radix for
549 * multiplications s.t. (BINT_RADIX/radix <= rio < BINT_RADIX).
550 */
551 maxi = BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))) / radix;
552 for (
553 rio = radix, dio = 1;
554 radix*rio < maxi;
555 rio *= radix, dio++
556 );
557
558
559 /* Now satisfy (BINT_RADIX/radix <= rio < BINT_RADIX) */
560 rio *= radix, dio++;
561
562
563 /*
564 * Convert the whole part using the specified base. First we
565 * need to estimate the number of bits needed for the result.
566 */
567 bpd = (ULong)(log((double)radix)/log(2.0)) + 1;
568 ndigs = (Length)(end - num);
569 nbits = ndigs*bpd;
570
571
572 /* If safe, compute as a C integer. */
573 if (nbits <= INT_LG_IMMED((8 * sizeof(IInt))-2))
574 {
575 /* Scan the small immediate integer */
576 ires = ulongSmallIntFrString(num, ndigs, radix);
577
578
579 /*
580 * Return the immediate result. If the number
581 * contained invalid characters then the result
582 * will be invalid. Check errno if required.
583 */
584 if (isNeg) ires = -ires;
585 return IntToBInt(ires)((BInt) ((Pointer)(((((long)(ires)) << 1) | 1))));
586 }
587
588
589 /* Allocate enough store for the result */
590 retval = bintAlloc(nbits);
591
592
593 /*
594 * Convert radix by interpreting string as a poly in radix
595 * `rio' and evaluating using Horner's rule. This means that
596 * we convert the number in chunks that will fit into an
597 * immediate integer. Start with a chunk big enough to ensure
598 * that the remaining chunks are all `dio' digits long.
599 */
600 l0 = ndigs % dio;
601 for (n = 0, l = l0; l > 0; l--)
602 {
603 IInt dig;
604
605 dig = (*num <= '9') ? (*num - '0') : (*num - 'A') + 10;
606 n = radix*n + dig;
607 num++;
608 }
609 retval = xintCopyInI(retval, n);
610
611
612 /* Now deal with the other chunks */
613 for (ndigs -= l0; ndigs > 0; ndigs -= dio)
614 {
615 for (n = 0, l = dio; l > 0; l--)
616 {
617 IInt dig;
618
619 dig = (*num <= '9') ? (*num - '0') : (*num - 'A') + 10;
620 n = radix*n + dig;
621 num++;
622 }
623 iintTimesPlusS(retval, retval, (BIntS) rio, (BIntS) n);
624 }
625
626
627 /* Deal with any negation */
628 IsNeg(retval)((retval)->isNeg) = isNeg;
629
630
631 /* Try to make it an immediate integer is possible */
632 return xintImmedIfCan(retval);
633}
634
635
636/* Convert a base 10 string representation to a big integer. */
637BInt
638bintScanFrString(String s, String *end)
639{
640 String t;
641 BInt b;
642 Bool isNeg = false((int) 0);
643 Length ndig;
644 IInt dim, dio;
645 ULong rim, rio;
646 IInt l, l0, n;
647
648 /*
649 * Determine rim: power of input radix for immediate representation.
650 * This is the largest power of 10 <= INT_MAX_IMMED.
651 * Determine rio: power of input radix for multiplications.
652 * This is the largest power of 10 < BINT_RADIX.
653 */
654 for (rim = 10, dim = 1; 10*rim <= INT_MAX_IMMED(- (long) ((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1)); rim *= 10, dim++)
655 ;
656 /*
657 * BUG -------------------------+
658 * V
659 */
660 for (rio = 10, dio = 1; 10*rio <= BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))); rio *= 10, dio++)
661 ;
662
663 /*
664 * Find beginning and end of number.
665 * Don't use strlen, since there may be trailing text.
666 */
667 while (isspace(*s)((*__ctype_b_loc ())[(int) ((*s))] & (unsigned short int)
_ISspace)
)
668 s++;
669 if (*s == '-') {
670 isNeg = true1;
671 s++;
672 }
673 while (*s == '0')
674 s++;
675 for (t = s; isdigit(*t)((*__ctype_b_loc ())[(int) ((*t))] & (unsigned short int)
_ISdigit)
; t++)
676 ;
677 ndig = t-s;
678
679 if (end) *end = t;
680 /*
681 * If safe, compute as a C integer.
682 */
683 if (ndig <= dim) {
684 for (n = 0; s != t; s++) n = 10*n + *s - '0';
685 if (isNeg) n = -n;
686 return IntToBInt(n)((BInt) ((Pointer)(((((long)(n)) << 1) | 1))));
687 }
688
689 /*
690 * Over-estimate number of bits by multiplying by 4, rather than
691 * log(10)/log(2) < 3.322.
692 */
693 b = bintAlloc(4*ndig);
694
695 /*
696 * Convert radix by interpreting string as a poly in radix "rio"
697 * and evaluating using Horner's rule.
698 */
699 l0 = ndig % dio;
700 for (n = 0, l = l0; l > 0; l--) n = 10*n + *s++ - '0';
701 b = xintCopyInI(b, n);
702
703 for (ndig -= l0; ndig > 0; ndig -= dio) {
704 for (n = 0, l = dio; l > 0; l--) n = 10*n + *s++ - '0';
705 iintTimesPlusS(b, b, (BIntS) rio, (BIntS) n);
706 }
707
708 IsNeg(b)((b)->isNeg) = isNeg;
709
710 b = xintImmedIfCan(b);
711
712 return b;
713}
714
715
716/****************************************************************************
717 *
718 * :: Basic Allocation
719 *
720 ****************************************************************************/
721
722BInt
723bintAllocPlaces(Length placea)
724{
725 BInt b;
726 b = (BInt) stoAlloc(OB_BInt2, fullsizeof(*b, placea, Placev(b)[0])(sizeof(*b) + (placea) * sizeof(((b)->placev)[0]) - 10 * sizeof
(((b)->placev)[0]))
);
727 Placea(b)((b)->placea) = placea;
728 Placec(b)((b)->placec) = placea;
729 IsNeg(b)((b)->isNeg) = false((int) 0);
730
731 return b;
732}
733
734BInt
735bintAlloc(Length bitc)
736{
737 return bintAllocPlaces(QUO_ROUND_UP(bitc, BINT_LG_RADIX)((bitc) % (((8 * sizeof(BIntS)))) ? (bitc)/(((8 * sizeof(BIntS
)))) + 1 : (bitc)/(((8 * sizeof(BIntS)))))
);
738}
739
740void
741bintFree(BInt b)
742{
743 if (IsImmed(b)((long)(b) & 1)) return;
744
745 stoFree((Pointer) b);
746}
747
748BInt
749bintNew(long n)
750{
751 if (INT_IS_IMMED(n)(((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1)<= (long
)(n) && (long)(n)<= (- (long) ((((IInt) 3) <<
((8 * sizeof(IInt))-2)) + 1)))
) return IntToBInt(n)((BInt) ((Pointer)(((((long)(n)) << 1) | 1))));
752
753 return xintStoreI(n);
754}
755
756BInt
757bintCopy(BInt bo)
758{
759 BInt bn;
760 Length i, c;
761
762 if (IsImmed(bo)((long)(bo) & 1)) return bo;
763
764 c = Placec(bo)((bo)->placec);
765 bn = bintAllocPlaces(c);
766
767 for (i = 0; i < c; i++) Placev(bn)((bn)->placev)[i] = Placev(bo)((bo)->placev)[i];
768 IsNeg(bn)((bn)->isNeg) = IsNeg(bo)((bo)->isNeg);
769
770 return bn;
771}
772
773BInt
774bintFrPlacev(Bool isNeg, Length placec, BIntS *data)
775{
776 BInt bint;
777 int i;
778
779 bint = bintAllocPlaces(placec);
780 IsNeg(bint)((bint)->isNeg) = isNeg;
781
782 for (i = placec - 1; i >= 0 && data[i] == 0; i--) ;
783
784 Placec(bint)((bint)->placec) = i+1;
785
786 for (; i >= 0; i--)
787 Placev(bint)((bint)->placev)[i] = data[i];
788 return xintImmedIfCan(bint);
789}
790
791#if (U16sPerUNotAsLong2 == 1)
792BInt
793bintFrPlacevS(Bool isNeg, Length placec, U16 *data)
794{
795 return bintFrPlacev(isNeg, placec, (BIntS*) data);
796}
797
798void
799bintToPlacevS(BInt b, int *psize, U16 **pdata)
800{
801 *psize = b->placec;
802 *pdata = b->placev;
803}
804
805void
806bintReleasePlacevS(U16 *pdata)
807{
808}
809#endif
810
811#if (U16sPerUNotAsLong2 == 2)
812BInt
813bintFrPlacevS(Bool isNeg, Length placec, U16 *data)
814{
815 BInt bint;
816 BIntS *bint_data;
817 int newc, i;
818
819 if (placec & 1)
820 bint_data = (BIntS*) data;
821 else
822 bint_data = (BIntS*) stoAlloc(OB_Other0, sizeof(BIntS) * (placec + 1));
823 newc = (placec+1)/2;
824 for (i = 0; i < newc-1; i++)
825 bint_data[i] = data[2*i] + (data[2*i+1] << bitsizeof(U16)(8 * sizeof(U16)));
826 bint_data[i] = (placec & 1) ?
827 data[2*i] :
828 data[2*i] + (data[2*i+1] << bitsizeof(U16)(8 * sizeof(U16)));
829
830 bint = bintFrPlacev(isNeg, newc, bint_data);
831
832 if (!(placec & 1))
833 stoFree(bint_data);
834 return bint;
835}
836
837void
838bintToPlacevS(BInt b, int *psize, U16 **pdata)
839{
840 BInt oldb;
841 U16 *data;
842 int placec;
843 int i;
844
845 oldb = b;
846 b = xintStore(b);
847 placec = b->placec;
848
849 data = (U16*) stoAlloc(OB_Other0, 2*placec*sizeof(U16));
850
851 for (i=0; i < placec; i++) {
852 data[2*i] = b->placev[i] & 0x0000FFFF;
853 data[2*i+1] = (b->placev[i] & 0xFFFF0000) >> 16;
854 }
855
856 if (data[2*placec - 1] == 0)
857 *psize = 2*placec - 1;
858 else
859 *psize = 2*placec;
860 *pdata = data;
861
862 if (oldb != b)
863 bintFree(b);
864}
865
866void
867bintReleasePlacevS(U16 *data)
868{
869 stoFree(data);
870}
871#endif
872
873/****************************************************************************
874 *
875 * :: Small integers
876 *
877 ****************************************************************************/
878
879Bool
880bintIsSmall(BInt b)
881{
882 return IsImmed(b)((long)(b) & 1);
883}
884
885long
886bintSmall(BInt b)
887{
888 return BIntToInt(b)((IInt) ((((long) (b))) >> 1));
889}
890
891
892/****************************************************************************
893 *
894 * :: General arithmetic
895 *
896 ****************************************************************************/
897localstatic BInt bintModi (BInt, unsigned long);
898localstatic ULong bintToULong (BInt);
899
900/*
901 * Special values
902 */
903BInt bint0 = BIntZero((BInt) ((((long)(0)) << 1) | 1));
904BInt bint1 = BIntOne((BInt) ((((long)(1)) << 1) | 1));
905
906/*
907 * b < 0 ?
908 */
909Bool
910bintIsNeg(BInt b)
911{
912 if (IsImmed(b)((long)(b) & 1)) return BIntToInt(b)((IInt) ((((long) (b))) >> 1)) < 0;
913
914 return IsNeg(b)((b)->isNeg);
915}
916
917/*
918 * b == 0 ?
919 */
920Bool
921bintIsZero(BInt b)
922{
923 return IsImmed(b)((long)(b) & 1) && BIntToInt(b)((IInt) ((((long) (b))) >> 1)) == 0;
924}
925
926/*
927 * b > 0 ?
928 */
929Bool
930bintIsPos(BInt b)
931{
932 if (IsImmed(b)((long)(b) & 1)) return BIntToInt(b)((IInt) ((((long) (b))) >> 1)) > 0;
933
934 return Placec(b)((b)->placec) > 0 && !IsNeg(b)((b)->isNeg);
935}
936
937/*
938 * a == b ?
939 */
940Bool
941bintEQ(BInt a, BInt b)
942{
943 Bool aImmed, bImmed;
944 IInt i, c;
945
946 if (Beq(a,b)((a) == (b))) return true1;
947
948 aImmed = IsImmed(a)((long)(a) & 1);
949 bImmed = IsImmed(b)((long)(b) & 1);
950
951 if (aImmed && bImmed) return BIntToInt(a)((IInt) ((((long) (a))) >> 1)) == BIntToInt(b)((IInt) ((((long) (b))) >> 1));
952 if (aImmed != bImmed) return false((int) 0);
953 if (IsNeg(a)((a)->isNeg) != IsNeg(b)((b)->isNeg)) return false((int) 0);
954 if (Placec(a)((a)->placec) != Placec(b)((b)->placec)) return false((int) 0);
955
956 c = Placec(a)((a)->placec);
957
958 for (i = 0; i < c; i++)
959 if (Placev(a)((a)->placev)[i] != Placev(b)((b)->placev)[i]) return false((int) 0);
960 return true1;
961}
962
963/*
964 * a < b ?
965 */
966Bool
967bintLT(BInt a, BInt b)
968{
969 Bool aImmed, bImmed;
970 IInt i, c;
971
972 if (Beq(a,b)((a) == (b))) return false((int) 0);
973
974 aImmed = IsImmed(a)((long)(a) & 1);
975 bImmed = IsImmed(b)((long)(b) & 1);
976
977 if (aImmed && bImmed) return BIntToInt(a)((IInt) ((((long) (a))) >> 1)) < BIntToInt(b)((IInt) ((((long) (b))) >> 1));
978 if (aImmed) return !IsNeg(b)((b)->isNeg);
979 if (bImmed) return IsNeg(a)((a)->isNeg);
980 if (IsNeg(a)((a)->isNeg) != IsNeg(b)((b)->isNeg)) return IsNeg(a)((a)->isNeg) && !IsNeg(b)((b)->isNeg);
981
982 if (IsNeg(a)((a)->isNeg)) {
983 if (Placec(a)((a)->placec)!= Placec(b)((b)->placec)) return Placec(a)((a)->placec) > Placec(b)((b)->placec);
984 c = Placec(a)((a)->placec);
985 for (i = c-1; i >= 0; i--) {
986 if (Placev(a)((a)->placev)[i] == Placev(b)((b)->placev)[i]) continue;
987 return Placev(a)((a)->placev)[i] > Placev(b)((b)->placev)[i];
988 }
989 return false((int) 0);
990 }
991 else {
992 if (Placec(a)((a)->placec)!= Placec(b)((b)->placec)) return Placec(a)((a)->placec) < Placec(b)((b)->placec);
993 c = Placec(a)((a)->placec);
994 for (i = c-1; i >= 0; i--) {
995 if (Placev(a)((a)->placev)[i] == Placev(b)((b)->placev)[i]) continue;
996 return Placev(a)((a)->placev)[i] < Placev(b)((b)->placev)[i];
997 }
998 return false((int) 0);
999 }
1000}
1001
1002/*
1003 * a > b ?
1004 */
1005Bool
1006bintGT(BInt a, BInt b)
1007{
1008 Bool aImmed, bImmed;
1009 IInt i, c;
1010
1011 if (Beq(a,b)((a) == (b))) return false((int) 0);
1012
1013 aImmed = IsImmed(a)((long)(a) & 1);
1014 bImmed = IsImmed(b)((long)(b) & 1);
1015
1016 if (aImmed && bImmed) return BIntToInt(a)((IInt) ((((long) (a))) >> 1)) > BIntToInt(b)((IInt) ((((long) (b))) >> 1));
1017 if (aImmed) return IsNeg(b)((b)->isNeg);
1018 if (bImmed) return !IsNeg(a)((a)->isNeg);
1019 if (IsNeg(a)((a)->isNeg) != IsNeg(b)((b)->isNeg)) return !IsNeg(a)((a)->isNeg) && IsNeg(b)((b)->isNeg);
1020
1021 if (IsNeg(a)((a)->isNeg)) {
1022 if (Placec(a)((a)->placec)!= Placec(b)((b)->placec)) return Placec(a)((a)->placec) < Placec(b)((b)->placec);
1023 c = Placec(a)((a)->placec);
1024 for (i = c-1; i >= 0; i--) {
1025 if (Placev(a)((a)->placev)[i] == Placev(b)((b)->placev)[i]) continue;
1026 return Placev(a)((a)->placev)[i] < Placev(b)((b)->placev)[i];
1027 }
1028 return false((int) 0);
1029 }
1030 else {
1031 if (Placec(a)((a)->placec)!= Placec(b)((b)->placec)) return Placec(a)((a)->placec) > Placec(b)((b)->placec);
1032 c = Placec(a)((a)->placec);
1033 for (i = c-1; i >= 0; i--) {
1034 if (Placev(a)((a)->placev)[i] == Placev(b)((b)->placev)[i]) continue;
1035 return Placev(a)((a)->placev)[i] > Placev(b)((b)->placev)[i];
1036 }
1037 return false((int) 0);
1038 }
1039}
1040
1041/*
1042 * Form a new value equal to the absolute value of a.
1043 */
1044BInt
1045bintAbs(BInt a)
1046{
1047 BInt r;
1048
1049 if (IsImmed(a)((long)(a) & 1)) {
1050 r = (BIntToInt(a)((IInt) ((((long) (a))) >> 1)) < 0) ? bintNew(-BIntToInt(a)((IInt) ((((long) (a))) >> 1))) : a;
1051 }
1052 else {
1053 r = bintCopy(a);
1054 IsNeg(r)((r)->isNeg) = false((int) 0);
1055 }
1056 return r;
1057}
1058
1059/*
1060 * Form a new value equal to -a.
1061 */
1062BInt
1063bintNegate(BInt a)
1064{
1065 BInt r;
1066
1067 if (IsImmed(a)((long)(a) & 1)) return IntToBInt(-BIntToInt(a))((BInt) ((Pointer)(((((long)(-((IInt) ((((long) (a))) >>
1)))) << 1) | 1))))
;
1068
1069 r = bintCopy(a);
1070 IsNeg(r)((r)->isNeg) = !IsNeg(r)((r)->isNeg);
1071 return r;
1072}
1073
1074#define BINT_NEGATE(r){ if (((long)(r) & 1)) (r) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (r))) >> 1)))) << 1) | 1))));
else ((r)->isNeg) = !((r)->isNeg); }
\
1075 { if (IsImmed(r)((long)(r) & 1)) (r) = IntToBInt(-BIntToInt(r))((BInt) ((Pointer)(((((long)(-((IInt) ((((long) (r))) >>
1)))) << 1) | 1))))
; else IsNeg(r)((r)->isNeg) = !IsNeg(r)((r)->isNeg); }
1076
1077/*
1078 * Add a and b to produce a newly allocated result.
1079 */
1080BInt
1081bintPlus(BInt a, BInt b)
1082{
1083 BInt r;
1084 Bool aImmed, bImmed, rImmed, aNeg, bNeg;
1085 IInt abitc, bbitc, rbitc;
1086
1087 /* Small integer case. */
1088 aImmed = IsImmed(a)((long)(a) & 1);
1089 bImmed = IsImmed(b)((long)(b) & 1);
1090
1091 if (aImmed && bImmed) {
1092 IInt ai = BIntToInt(a)((IInt) ((((long) (a))) >> 1));
1093 IInt bi = BIntToInt(b)((IInt) ((((long) (b))) >> 1));
1094 IInt ki, ri;
1095 PlusStep(ki,ri, ai, bi, int0){ BIntD r_ = (BIntD)(ai)+(BIntD)(bi)+(BIntD)(((int) 0)); BIntS
k_ = (r_ >= (BIntD) (((unsigned long) 1) << ((8 * sizeof
(BIntS))))); if (k_) r_ -= (((unsigned long) 1) << ((8 *
sizeof(BIntS)))); (ri) = r_; (ki) = k_; }
;
1096 if (ki == 0 && INT_IS_IMMED(ri)(((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1)<= (long
)(ri) && (long)(ri)<= (- (long) ((((IInt) 3) <<
((8 * sizeof(IInt))-2)) + 1)))
) return IntToBInt(ri)((BInt) ((Pointer)(((((long)(ri)) << 1) | 1))));
1097 }
1098
1099 if (aImmed) a = xintStore(a);
1100 if (bImmed) b = xintStore(b);
1101
1102 aNeg = bintIsNeg(a);
1103 bNeg = bintIsNeg(b);
1104
1105 if (aNeg && bNeg) {
1106 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
; if (!Beq(a,b)((a) == (b))) BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1107 r = bintPlus(a, b);
1108 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
; if (!Beq(a,b)((a) == (b))) BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1109 BINT_NEGATE(r){ if (((long)(r) & 1)) (r) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (r))) >> 1)))) << 1) | 1))));
else ((r)->isNeg) = !((r)->isNeg); }
;
1110 }
1111 else if (aNeg) {
1112 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
;
1113 r = bintMinus(b, a);
1114 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
;
1115 }
1116 else if (bNeg) {
1117 BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1118 r = bintMinus(a, b);
1119 BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1120 }
1121 else {
1122 /* General case. */
1123 abitc = bintLength(a);
1124 bbitc = bintLength(b);
1125
1126 if (abitc < bbitc) {
1127 r = a; rbitc = abitc; rImmed = aImmed;
1128 a = b; abitc = bbitc; aImmed = bImmed;
1129 b = r; bbitc = rbitc; bImmed = rImmed;
1130 }
1131
1132 rbitc = abitc + 1; /* +1 for potential carry */
1133
1134 r = bintAlloc(rbitc);
1135
1136 iintPlus(r, a, b);
1137
1138 r = xintImmedIfCan(r);
1139 }
1140
1141 if (aImmed) bintFree(a);
1142 if (bImmed) bintFree(b);
1143 return r;
1144}
1145
1146/*
1147 * Subtract b from a to produce a newly allocated result.
1148 */
1149BInt
1150bintMinus(BInt a, BInt b)
1151{
1152 BInt r;
1153 Bool aImmed, bImmed, rImmed, aNeg, bNeg, rNeg;
1154
1155 /* Small integer case. */
1156 aImmed = IsImmed(a)((long)(a) & 1);
1157 bImmed = IsImmed(b)((long)(b) & 1);
1158
1159 if (aImmed && bImmed) {
1160 IInt ai = BIntToInt(a)((IInt) ((((long) (a))) >> 1));
1161 IInt bi = BIntToInt(b)((IInt) ((((long) (b))) >> 1));
1162 IInt ri = ai - bi;
1163 if (INT_IS_IMMED(ri)(((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1)<= (long
)(ri) && (long)(ri)<= (- (long) ((((IInt) 3) <<
((8 * sizeof(IInt))-2)) + 1)))
) return IntToBInt(ri)((BInt) ((Pointer)(((((long)(ri)) << 1) | 1))));
1164 }
1165
1166 if (aImmed) a = xintStore(a);
1167 if (bImmed) b = xintStore(b);
1168
1169 aNeg = bintIsNeg(a);
1170 bNeg = bintIsNeg(b);
1171
1172 if (aNeg && bNeg) {
1173 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
; if (!Beq(a,b)((a) == (b))) BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1174 r = bintMinus(b, a);
1175 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
; if (!Beq(a,b)((a) == (b))) BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1176 }
1177 else if (aNeg) {
1178 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
;
1179 r = bintPlus(a, b);
1180 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
;
1181 BINT_NEGATE(r){ if (((long)(r) & 1)) (r) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (r))) >> 1)))) << 1) | 1))));
else ((r)->isNeg) = !((r)->isNeg); }
;
1182 }
1183 else if (bNeg) {
1184 BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1185 r = bintPlus(a, b);
1186 BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1187 }
1188 else {
1189 /* General case. */
1190
1191 /* If a < b, compute -(b-a). */
1192 rNeg = bintLT(a, b);
1193 if (rNeg) {
1194 r = a; rImmed = aImmed;
1195 a = b; aImmed = bImmed;
1196 b = r; bImmed = rImmed;
1197 }
1198
1199 r = bintAllocPlaces(Placec(a)((a)->placec));
1200
1201 iintMinus(r, a, b);
1202 IsNeg(r)((r)->isNeg) = rNeg;
1203
1204 r = xintImmedIfCan(r);
1205 }
1206
1207 if (aImmed) bintFree(a);
1208 if (bImmed) bintFree(b);
1209
1210 return r;
1211}
1212
1213/*
1214 * Multiply a and b to produce a newly allocated result.
1215 */
1216BInt
1217bintTimes(BInt a, BInt b)
1218{
1219 BInt r;
1220 Bool aImmed, bImmed, aNeg, bNeg;
1221 IInt ac, bc, rc;
1222
1223 /* Small integer case. */
1224 aImmed = IsImmed(a)((long)(a) & 1);
1225 bImmed = IsImmed(b)((long)(b) & 1);
1226
1227 if (aImmed && bImmed) {
1228 IInt ai = BIntToInt(a)((IInt) ((((long) (a))) >> 1));
1229 IInt bi = BIntToInt(b)((IInt) ((((long) (b))) >> 1));
1230 if (INT_IS_HALF(ai)((-((((IInt) 1)<<((((8 * sizeof(IInt))-2)/2))) -1)) <=
(long)(ai) && (long)(ai)<= ((((IInt) 1)<<((
((8 * sizeof(IInt))-2)/2))) -1))
&& INT_IS_HALF(bi)((-((((IInt) 1)<<((((8 * sizeof(IInt))-2)/2))) -1)) <=
(long)(bi) && (long)(bi)<= ((((IInt) 1)<<((
((8 * sizeof(IInt))-2)/2))) -1))
) return bintNew(ai*bi);
1231 }
1232 if (aImmed) {
1233 IInt ai = BIntToInt(a)((IInt) ((((long) (a))) >> 1));
1234 if (ai == 0) return IntToBInt(int0)((BInt) ((Pointer)(((((long)(((int) 0))) << 1) | 1))));
1235 if (ai == 1) return bintCopy(b);
1236 if (ai ==-1) return bintNegate(b);
1237 }
1238 if (bImmed) {
1239 IInt bi = BIntToInt(b)((IInt) ((((long) (b))) >> 1));
1240 if (bi == 0) return IntToBInt(int0)((BInt) ((Pointer)(((((long)(((int) 0))) << 1) | 1))));
1241 if (bi == 1) return bintCopy(a);
1242 if (bi ==-1) return bintNegate(a);
1243 }
1244
1245 if (aImmed) a = xintStore(a);
1246 if (bImmed) b = xintStore(b);
1247
1248 aNeg = bintIsNeg(a);
1249 bNeg = bintIsNeg(b);
1250
1251 if (aNeg && bNeg) {
1252 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
; if (!Beq(a,b)((a) == (b))) BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1253 r = bintTimes(a, b);
1254 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
; if (!Beq(a,b)((a) == (b))) BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1255 }
1256 else if (aNeg) {
1257 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
;
1258 r = bintTimes(a, b);
1259 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
;
1260 BINT_NEGATE(r){ if (((long)(r) & 1)) (r) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (r))) >> 1)))) << 1) | 1))));
else ((r)->isNeg) = !((r)->isNeg); }
;
1261 }
1262 else if (bNeg) {
1263 BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1264 r = bintTimes(a, b);
1265 BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1266 BINT_NEGATE(r){ if (((long)(r) & 1)) (r) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (r))) >> 1)))) << 1) | 1))));
else ((r)->isNeg) = !((r)->isNeg); }
;
1267 }
1268 else {
1269 /* General case. */
1270
1271 ac = Placec(a)((a)->placec);
1272 bc = Placec(b)((b)->placec);
1273 rc = ac + bc;
1274
1275 r = bintAllocPlaces(rc);
1276
1277 iintTimes(r, a, b);
1278
1279 r = xintImmedIfCan(r);
1280 }
1281
1282 if (aImmed) bintFree(a);
1283 if (bImmed) bintFree(b);
1284
1285 return r;
1286}
1287
1288
1289/*
1290 * Divide a by b to produce a newly allocated quotient as the result.
1291 * If the pointer pr != 0, then a newly allocated remainder is returned via it.
1292 */
1293BInt
1294bintDivide(BInt *pr, BInt a, BInt b)
1295{
1296 BInt q, r;
1297 Bool aImmed, bImmed, aNeg, bNeg;
1298 IInt n, m;
1299
1300 /* Small integer case not yet handled. */
1301 aImmed = IsImmed(a)((long)(a) & 1);
1302 bImmed = IsImmed(b)((long)(b) & 1);
1303
1304 if (aImmed) a = xintStore(a);
1305 if (bImmed) b = xintStore(b);
1306
1307 aNeg = bintIsNeg(a);
1308 bNeg = bintIsNeg(b);
1309
1310 if (aNeg && bNeg) {
1311 /* (q,r) = divide(-a,-b); if (r != 0) {q++; r = b-r;} */
1312 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
; if (!Beq(a,b)((a) == (b))) BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1313 q = bintDivide(&r, a, b);
1314 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
; if (!Beq(a,b)((a) == (b))) BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1315
1316 BINT_NEGATE(r){ if (((long)(r) & 1)) (r) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (r))) >> 1)))) << 1) | 1))));
else ((r)->isNeg) = !((r)->isNeg); }
;
1317 }
1318 else if (aNeg) {
1319 /* (q,r) = divide(-a,b); q = -q-1; r = b-r; */
1320 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
;
1321 q = bintDivide(&r, a, b);
1322 BINT_NEGATE(a){ if (((long)(a) & 1)) (a) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (a))) >> 1)))) << 1) | 1))));
else ((a)->isNeg) = !((a)->isNeg); }
;
1323
1324 BINT_NEGATE(q){ if (((long)(q) & 1)) (q) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (q))) >> 1)))) << 1) | 1))));
else ((q)->isNeg) = !((q)->isNeg); }
;
1325 BINT_NEGATE(r){ if (((long)(r) & 1)) (r) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (r))) >> 1)))) << 1) | 1))));
else ((r)->isNeg) = !((r)->isNeg); }
;
1326 }
1327 else if (bNeg) {
1328 /* (q,r) = divide(a,-b); q = -q; */
1329 BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1330 q = bintDivide(&r, a, b);
1331 BINT_NEGATE(b){ if (((long)(b) & 1)) (b) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (b))) >> 1)))) << 1) | 1))));
else ((b)->isNeg) = !((b)->isNeg); }
;
1332
1333 BINT_NEGATE(q){ if (((long)(q) & 1)) (q) = ((BInt) ((Pointer)(((((long)
(-((IInt) ((((long) (q))) >> 1)))) << 1) | 1))));
else ((q)->isNeg) = !((q)->isNeg); }
;
1334 }
1335 else {
1336 /* General case. */
1337
1338 n = Placec(b)((b)->placec);
1339 m = Placec(a)((a)->placec) - n; if (m < 0) m = 0;
1340
1341 q = bintAllocPlaces(m+1);
1342 r = bintAllocPlaces(n+m+1);
1343
1344 iintDivide(q, r, a, b); /*!! Should shrink r here. */
1345
1346 q = xintImmedIfCan(q);
1347 r = xintImmedIfCan(r);
1348 }
1349
1350 if (aImmed) bintFree(a);
1351 if (bImmed) bintFree(b);
1352
1353 if (pr) *pr = r; else bintFree(r);
1354 return q;
1355}
1356
1357BInt
1358bintMod(BInt a, BInt b)
1359{
1360 BInt r, q;
1361 Bool neg;
1362 /*
1363 * Compute a mod b via horner's rule if b fits into a single word,
1364 * use bintDivide o/wise.
1365 */
1366 neg = bintIsNeg(a);
1367 if (neg)
1368 a = bintNegate(a);
1369
1370 if (bintIsNeg(b))
1371 b = bintNegate(b);
1372
1373 if (IsImmed(b)((long)(b) & 1)) {
1374 r = bintModi(a, (ULong) BIntToInt(b)((IInt) ((((long) (b))) >> 1)));
1375 }
1376 else if (bintLength(b) < bitsizeof(ULong)(8 * sizeof(ULong))) {
1377 /* Can't handle 32 bit divisors as yet! */
1378 r = bintModi(a, bintToULong(b));
1379 }
1380 else {
1381 q = bintDivide(&r, (BInt) a, (BInt) b);
1382 bintFree(q);
1383 }
1384 if (neg)
1385 r = xintNegate(r);
1386
1387 return r;
1388}
1389
1390localstatic BInt
1391bintModi(BInt a, ULong b)
1392{
1393 ULong d = 1L << bitsizeof(BIntS)(8 * sizeof(BIntS));
1394 ULong r;
1395 ULong acc;
1396 int i;
1397
1398 assert(!bintIsNeg(a))do { if (!(!bintIsNeg(a))) _do_assert(("!bintIsNeg(a)"),"bigint.c"
,1398); } while (0)
;
1399
1400 if (IsImmed(a)((long)(a) & 1)) {
1401 return bintNew(BIntToInt(a)((IInt) ((((long) (a))) >> 1)) % b);
1402 }
1403
1404 if (b < d) {
1405 d = d % b;
1406 i = Placec(a)((a)->placec) - 1;
1407 acc = Placev(a)((a)->placev)[i] % b;
1408 i--;
1409 while (i>=0) {
1410 long tmp;
1411 /* acc = acc mod* d mod+ a[i] */
1412 acc = (acc * d) % b;
1413 tmp = acc - b + Placev(a)((a)->placev)[i] % b;
1414 if (tmp < 0) tmp += b;
1415 acc = tmp;
1416 i--;
1417 }
1418 }
1419 else {
1420 /* b larger than 1 halfword */
1421 i = Placec(a)((a)->placec) - 1;
1422 acc = Placev(a)((a)->placev)[i];
1423 i--;
1424 while (i>=0) {
1425 /* acc = acc mod* d mod+ a[i] */
1426 ULong hi, lo, rem;
1427 long tmp;
1428 /*xxTimesDouble(&hi, &lo, acc, d);*/
1429 hi = acc >> bitsizeof(BIntS)(8 * sizeof(BIntS));
1430 lo = acc << bitsizeof(BIntS)(8 * sizeof(BIntS));
1431 rem = xxModDouble(hi, lo, b);
1432 tmp = (rem - (long) b) + Placev(a)((a)->placev)[i];
1433 if (tmp < 0)
1434 tmp += b;
1435 acc = tmp;
1436 i--;
1437 }
1438 }
1439 r = acc;
1440 return bintNew(r);
1441}
1442
1443localstatic ULong
1444bintToULong(BInt b)
1445{
1446 ULong res;
1447 if (bintIsSmall(b))
1448 return bintSmall(b);
1449
1450 res = (ULong) Placev(b)((b)->placev)[0] + ( ((ULong) Placev(b)((b)->placev)[1]) << bitsizeof(BIntS)(8 * sizeof(BIntS)));
1451
1452 return res;
1453}
1454
1455/*
1456 * The length of b, in bits. I.e. cieling(lg(abs(b))).
1457 * Define the bit length of zero to be one bit.
1458 */
1459Length
1460bintLength(BInt b)
1461{
1462 Length res;
1463 if (IsImmed(b)((long)(b) & 1)) return intLength(BIntToInt(b)((IInt) ((((long) (b))) >> 1)));
1464 res = BINT_LG_RADIX((8 * sizeof(BIntS)))*(Placec(b)((b)->placec)-1) + uintLength(Placev(b)((b)->placev)[Placec(b)((b)->placec)-1]);
1465 return res;
1466}
1467
1468
1469/*
1470 * Extract the ix-th bit of b. I.e. the coef of 2**ix.
1471 * !! This should handle negative numbers.
1472 */
1473Bool
1474bintBit(BInt b, Length ix)
1475{
1476 Length cq, cr;
1477
1478 if (IsImmed(b)((long)(b) & 1)) return intBit(BIntToInt(b)((IInt) ((((long) (b))) >> 1)), ix);
1479
1480 cq = ix / BINT_LG_RADIX((8 * sizeof(BIntS)));
1481 cr = ix % BINT_LG_RADIX((8 * sizeof(BIntS)));
1482
1483 return (cq < Placec(b)((b)->placec)) && (Placev(b)((b)->placev)[cq] & (1<<cr)) != 0;
1484}
1485
1486/*
1487 * Shift b by n bits. I.e. compute b*2**n.
1488 */
1489BInt
1490bintShift(BInt b, int n)
1491{
1492 BInt r;
1493 IInt bbitc, rbitc;
1494 Bool bImmed;
1495
1496 bImmed = IsImmed(b)((long)(b) & 1);
1497 bbitc = bintLength(b);
1498 rbitc = bbitc + n;
1499
1500 if (b == bint0) return bint0;
2
Assuming 'b' is not equal to 'bint0'
1501 if (bbitc == 0 || rbitc <= 0)
3
Assuming 'bbitc' is not equal to 0
4
Assuming 'rbitc' is > 0
1502 return IntToBInt(int0)((BInt) ((Pointer)(((((long)(((int) 0))) << 1) | 1))));
1503 if (bImmed && rbitc <= INT_LG_IMMED((8 * sizeof(IInt))-2)) {
5
Assuming 'bImmed' is 0
1504 IInt i = BIntToInt(b)((IInt) ((((long) (b))) >> 1));
1505 UIInt u = (i > 0) ? i : -i;
1506 u = (n > 0) ? u << n : u >> -n;
1507 return IntToBInt((i > 0) ? u : -(IInt)u)((BInt) ((Pointer)(((((long)((i > 0) ? u : -(IInt)u)) <<
1) | 1))))
;
1508 }
1509 if (bImmed
5.1
'bImmed' is 0
) b = xintStore(b);
6
Taking false branch
1510 r = bintAlloc(rbitc);
1511
1512 iintShift(r, b, n);
7
Calling 'iintShift'
1513
1514 if (bImmed) bintFree(b);
1515 if (rbitc <= INT_LG_IMMED((8 * sizeof(IInt))-2)) r = xintImmedIfCan(r);
1516
1517 return r;
1518}
1519
1520BInt
1521bintShiftRem(BInt b, int n)
1522{
1523 BInt r;
1524 int i, top;
1525 /* Returns lowest `n' bits from b. */
1526
1527 if (IsImmed(b)((long)(b) & 1)) {
1528 IInt x = BIntToInt(b)((IInt) ((((long) (b))) >> 1));
1529 return IntToBInt(x & ((1 << n) - 1))((BInt) ((Pointer)(((((long)(x & ((1 << n) - 1))) <<
1) | 1))))
;
1530 }
1531
1532 r = bintAlloc(n);
1533
1534 for (i=0; i<Placea(r)((r)->placea) - 1; i++) Placev(r)((r)->placev)[i] = Placev(b)((b)->placev)[i];
1535 top = n - BINT_LG_RADIX((8 * sizeof(BIntS)))*(Placec(r)((r)->placec) - 1);
1536 Placev(r)((r)->placev)[i] = Placev(b)((b)->placev)[i] & ((1<< top) - 1);
1537
1538 return xintImmedIfCan(r);
1539}
1540
1541/****************************************************************************
1542 *
1543 * :: Low-level, fine control allocation
1544 *
1545 ****************************************************************************/
1546
1547/*
1548 * Allocate a new, stored integer value.
1549 */
1550BInt
1551xintStoreI(long n)
1552{
1553 BInt b;
1554 ULong u;
1555 IInt a;
1556
1557 u = (n < 0) ? -n : n;
1558 for (a = 1; ; a += 1, u >>= BINT_LG_RADIX((8 * sizeof(BIntS))))
1559 if( u < BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))) ) break;
1560 b = bintAllocPlaces(a);
1561 return xintCopyInI(b, n);
1562}
1563
1564/*
1565 * Convert b to a stored representation.
1566 */
1567BInt
1568xintStore(BInt b)
1569{
1570 if (IsImmed(b)((long)(b) & 1)) return xintStoreI(BIntToInt(b)((IInt) ((((long) (b))) >> 1)));
1571
1572 return b;
1573}
1574
1575/*
1576 * Convert b to an immeditate (non-stored) representation, if possible.
1577 */
1578BInt
1579xintImmedIfCan(BInt b)
1580{
1581 Length pb;
1582 ULong u = 0;
1583
1584 if (IsImmed(b)((long)(b) & 1)) return b;
1585
1586 pb = Placec(b)((b)->placec);
1587
1588 /* Special case all 32-bit cases */
1589 if (pb == 0)
1590 return IntToBInt(int0)((BInt) ((Pointer)(((((long)(((int) 0))) << 1) | 1))));
1591 if (pb == 1 || pb == 2) {
1592 if (pb == 1)
1593 u = Placev(b)((b)->placev)[0];
1594 else
1595 u = ((BIntD)(Placev(b)((b)->placev)[1]) << BINT_LG_RADIX((8 * sizeof(BIntS))))
1596 + Placev(b)((b)->placev)[0];
1597 if (IsNeg(b)((b)->isNeg))
1598 return u > -(long)INT_MIN_IMMED((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1)
1599 ? b : (BInt) ptrFrLong(MkImmed(-(IInt)u))((Pointer)(((((long)(-(IInt)u)) << 1) | 1)));
1600 else
1601 return u > INT_MAX_IMMED(- (long) ((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1))
1602 ? b : (BInt) ptrFrLong(MkImmed(u))((Pointer)(((((long)(u)) << 1) | 1)));
1603 }
1604
1605
1606 /* For cases where 2*sizeof(BIntS) < sizeof(BInt) */
1607 if (pb*BINT_LG_RADIX((8 * sizeof(BIntS))) <= bitsizeof(IInt)(8 * sizeof(IInt))) {
1608 int i;
1609 for (i = pb - 1; i>= 0; i--)
1610 u = (u << BINT_LG_RADIX((8 * sizeof(BIntS)))) + Placev(b)((b)->placev)[i];
1611 if (IsNeg(b)((b)->isNeg))
1612 return (u > -INT_MIN_IMMED((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1)) ? b
1613 : (BInt) ptrFrLong(MkImmed(-u))((Pointer)(((((long)(-u)) << 1) | 1)));
1614 else
1615 return (u > INT_MAX_IMMED(- (long) ((((IInt) 3) << ((8 * sizeof(IInt))-2)) + 1))) ? b
1616 : (BInt) ptrFrLong(MkImmed(u))((Pointer)(((((long)(u)) << 1) | 1)));
1617 }
1618
1619 return b;
1620}
1621
1622/*
1623 * Place integer value n into stored BInt b.
1624 * If b is not big enough, then it is reallocated.
1625 */
1626BInt
1627xintCopyInI(BInt b, long n)
1628{
1629 ULong u, ut;
1630 IInt i, c, a;
1631 assert(!IsImmed(b))do { if (!(!((long)(b) & 1))) _do_assert(("!IsImmed(b)"),
"bigint.c",1631); } while (0)
;
1632
1633 u = (n<0)? -n : n;
1634 c = Placea(b)((b)->placea);
1635
1636 /* Quick test for usual case. */
1637 if (u < BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))) && c > 0) {
1638 Placev(b)((b)->placev)[0] = u;
1639 Placec(b)((b)->placec) = 1;
1640 IsNeg(b)((b)->isNeg) = (n < 0);
1641 return b;
1642 }
1643
1644 /* Multi-word case */
1645 ut = u; for (a = 0; ut != 0; a++) ut /= BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS))));
1646
1647 if (a > c) {
1648 bintFree(b);
1649 b = bintAllocPlaces(a);
1650 c = a;
1651 }
1652 for (i = 0; u != 0 && i < c; i++) {
1653 Placev(b)((b)->placev)[i] = u % BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS))));
1654 u = u / BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS))));
1655 }
1656 Placec(b)((b)->placec) = i;
1657
1658 IsNeg(b)((b)->isNeg) = (n < 0);
1659 return b;
1660}
1661
1662
1663/*
1664 * Ensure b can contain at least bitc bits.
1665 */
1666BInt
1667xintNeeds(BInt b, Length bitc)
1668{
1669 BInt bn;
1670 Length i, c;
1671
1672 if (IsImmed(b)((long)(b) & 1)) {
1673 if (bitc <= INT_LG_IMMED((8 * sizeof(IInt))-2))
1674 return b;
1675 else
1676 return xintCopyInI(bintAlloc(bitc), BIntToInt(b)((IInt) ((((long) (b))) >> 1)));
1677 }
1678
1679 if (Placea(b)((b)->placea)*BINT_LG_RADIX((8 * sizeof(BIntS))) >= bitc) return b;
1680
1681 bn = bintAlloc(bitc);
1682 c = Placec(b)((b)->placec);
1683 for (i = 0; i < c; i++) Placev(bn)((bn)->placev)[i] = Placev(b)((b)->placev)[i];
1684 Placec(bn)((bn)->placec) = Placec(b)((b)->placec);
1685 IsNeg(bn)((bn)->isNeg) = IsNeg(b)((b)->isNeg);
1686 bintFree(b);
1687
1688 return bn;
1689}
1690
1691
1692/*
1693 * Operations which free their operands.
1694 */
1695int
1696xintPrint(FILE *fout, BInt a)
1697{
1698 int cc = bintPrint(fout, a);
1699 bintFree(a);
1700 return cc;
1701}
1702
1703int
1704xintPrint2(FILE *fout, BInt a)
1705{
1706 int cc = bintPrint2(fout, a);
1707 bintFree(a);
1708 return cc;
1709}
1710
1711int
1712xintPrint16(FILE *fout, BInt a)
1713{
1714 int cc = bintPrint16(fout, a);
1715 bintFree(a);
1716 return cc;
1717}
1718
1719BInt
1720xintNegate(BInt a)
1721{
1722 BInt r = bintNegate(a);
1723 bintFree(a);
1724 return r;
1725}
1726
1727BInt
1728xintPlus(BInt a, BInt b)
1729{
1730 BInt r = bintPlus(a, b);
1731 bintFree(a);
1732 bintFree(b);
1733 return r;
1734}
1735
1736BInt
1737xintMinus(BInt a, BInt b)
1738{
1739 BInt r = bintMinus(a, b);
1740 bintFree(a);
1741 bintFree(b);
1742 return r;
1743}
1744
1745BInt
1746xintTimes(BInt a, BInt b)
1747{
1748 BInt r = bintTimes(a, b);
1749 bintFree(a);
1750 bintFree(b);
1751 return r;
1752}
1753
1754BInt
1755xintDivide(BInt *pr, BInt a, BInt b)
1756{
1757 BInt q = bintDivide(pr, a, b);
1758 bintFree(a);
1759 bintFree(b);
1760 return q;
1761}
1762
1763BInt
1764xintShift(BInt a, int n)
1765{
1766 BInt r = bintShift(a, n);
1
Calling 'bintShift'
1767 bintFree(a);
1768 return r;
1769}
1770
1771/*****************************************************************************
1772 *
1773 * :: Low-level, non-allocating operations
1774 *
1775 * Arithmetic is done with the macros PlusStep, TimesDouble, etc.
1776 *
1777 ****************************************************************************/
1778
1779/*
1780 * Place the value abs(a) in r.
1781 */
1782void
1783iintAbs(BInt r, BInt a)
1784{
1785 IInt i, c;
1786
1787 assert(!IsImmed(r) && !IsImmed(a) && Placea(r)>=Placec(a))do { if (!(!((long)(r) & 1) && !((long)(a) & 1
) && ((r)->placea)>=((a)->placec))) _do_assert
(("!IsImmed(r) && !IsImmed(a) && Placea(r)>=Placec(a)"
),"bigint.c",1787); } while (0)
;
1788
1789 IsNeg(r)((r)->isNeg) = false((int) 0);
1790
1791 if (Beq(r,a)((r) == (a))) return;
1792
1793 c = Placec(a)((a)->placec);
1794
1795 for (i = 0; i < c; i++) Placev(r)((r)->placev)[i] = Placev(a)((a)->placev)[i];
1796 Placec(r)((r)->placec) = Placec(a)((a)->placec);
1797}
1798
1799/*
1800 * Place the value -a in r.
1801 */
1802void
1803iintNegate(BInt r, BInt a)
1804{
1805 IInt i, c;
1806
1807 assert(!IsImmed(r) && !IsImmed(a) && Placea(r)>=Placec(a))do { if (!(!((long)(r) & 1) && !((long)(a) & 1
) && ((r)->placea)>=((a)->placec))) _do_assert
(("!IsImmed(r) && !IsImmed(a) && Placea(r)>=Placec(a)"
),"bigint.c",1807); } while (0)
;
1808
1809 IsNeg(r)((r)->isNeg) = !IsNeg(a)((a)->isNeg);
1810
1811 if (Beq(r,a)((r) == (a))) return;
1812
1813 c = Placec(a)((a)->placec);
1814
1815 for (i = 0; i < c; i++) Placev(r)((r)->placev)[i] = Placev(a)((a)->placev)[i];
1816 Placec(r)((r)->placec) = Placec(a)((a)->placec);
1817}
1818
1819/*
1820 * Add non-negative integers a and b and place result in preallocated r.
1821 * It is assumed that a is greater than b.
1822 * The result r, can be an alias for a or b.
1823 */
1824void
1825iintPlus(BInt r, BInt a, BInt b)
1826{
1827 BIntS s, k; /* k = 0 or 1 */
1828 IInt i, ac, bc;
1829
1830 assert(!IsImmed(a) && !IsImmed(b))do { if (!(!((long)(a) & 1) && !((long)(b) & 1
))) _do_assert(("!IsImmed(a) && !IsImmed(b)"),"bigint.c"
,1830); } while (0)
;
1831 assert(!IsNeg(a) && !IsNeg(b))do { if (!(!((a)->isNeg) && !((b)->isNeg))) _do_assert
(("!IsNeg(a) && !IsNeg(b)"),"bigint.c",1831); } while
(0)
;
1832 assert(Placec(a) >= Placec(b))do { if (!(((a)->placec) >= ((b)->placec))) _do_assert
(("Placec(a) >= Placec(b)"),"bigint.c",1832); } while (0)
;
1833 assert(!IsImmed(r) && Placea(r) >= Placec(a))do { if (!(!((long)(r) & 1) && ((r)->placea) >=
((a)->placec))) _do_assert(("!IsImmed(r) && Placea(r) >= Placec(a)"
),"bigint.c",1833); } while (0)
;
1834
1835 ac = Placec(a)((a)->placec);
1836 bc = Placec(b)((b)->placec);
1837
1838 k = 0;
1839
1840 for (i = 0; i < bc; i++) {
1841 PlusStep(k, s, Placev(a)[i], Placev(b)[i], k){ BIntD r_ = (BIntD)(((a)->placev)[i])+(BIntD)(((b)->placev
)[i])+(BIntD)(k); BIntS k_ = (r_ >= (BIntD) (((unsigned long
) 1) << ((8 * sizeof(BIntS))))); if (k_) r_ -= (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); (s) = r_; (k) = k_
; }
;
1842 Placev(r)((r)->placev)[i] = s;
1843 }
1844
1845 for ( ; i < ac && k; i++) {
1846 PlusStep(k, s, Placev(a)[i], int0, k){ BIntD r_ = (BIntD)(((a)->placev)[i])+(BIntD)(((int) 0))+
(BIntD)(k); BIntS k_ = (r_ >= (BIntD) (((unsigned long) 1)
<< ((8 * sizeof(BIntS))))); if (k_) r_ -= (((unsigned long
) 1) << ((8 * sizeof(BIntS)))); (s) = r_; (k) = k_; }
;
1847 Placev(r)((r)->placev)[i] = s;
1848 }
1849
1850 if (!k && Beq(r,a)((r) == (a))) return;
1851
1852 for ( ; i < ac; i++) {
1853 Placev(r)((r)->placev)[i] = Placev(a)((a)->placev)[i];
1854 }
1855
1856 if (k)
1857 Placev(r)((r)->placev)[i++] = k;
1858
1859 Placec(r)((r)->placec) = i;
1860}
1861
1862/*
1863 * Subtract non-negative integers a and b and place result in preallocated r.
1864 * It is assumed that a >= b >= 0.
1865 * The result r, can be an alias for a or b.
1866 *
1867 * This is Algorithm S of Knuth Volume 2, Section 4.3.1.
1868 */
1869void
1870iintMinus(BInt r, BInt a, BInt b)
1871{
1872 BIntS s, kp1; /* kp1 = k+1. k = 0 or -1 */
1873 IInt i, ac, bc;
1874
1875 assert(!IsImmed(a) && !IsImmed(b))do { if (!(!((long)(a) & 1) && !((long)(b) & 1
))) _do_assert(("!IsImmed(a) && !IsImmed(b)"),"bigint.c"
,1875); } while (0)
;
1876 assert(!IsNeg(a) && !IsNeg(b))do { if (!(!((a)->isNeg) && !((b)->isNeg))) _do_assert
(("!IsNeg(a) && !IsNeg(b)"),"bigint.c",1876); } while
(0)
;
1877 assert(Placec(a) >= Placec(b))do { if (!(((a)->placec) >= ((b)->placec))) _do_assert
(("Placec(a) >= Placec(b)"),"bigint.c",1877); } while (0)
;
1878 assert(!IsImmed(r) && Placea(r) >= Placec(a))do { if (!(!((long)(r) & 1) && ((r)->placea) >=
((a)->placec))) _do_assert(("!IsImmed(r) && Placea(r) >= Placec(a)"
),"bigint.c",1878); } while (0)
;
1879
1880 ac = Placec(a)((a)->placec);
1881 bc = Placec(b)((b)->placec);
1882
1883 kp1 = 1;
1884
1885 for (i = 0; i < bc; i++) {
1886 MinusStep(kp1, s, Placev(a)[i], Placev(b)[i], kp1){ BIntD r_ = (BIntD)(((a)->placev)[i])+(BIntD)((((((unsigned
long) 1) << ((8 * sizeof(BIntS)))) - 1) - (((b)->placev
)[i])))+(BIntD)(kp1); BIntS k_ = (r_ >= (BIntD) (((unsigned
long) 1) << ((8 * sizeof(BIntS))))); if (k_) r_ -= (((
unsigned long) 1) << ((8 * sizeof(BIntS)))); (s) = r_; (
kp1) = k_; }
;
1887 Placev(r)((r)->placev)[i] = s;
1888 }
1889
1890 for ( ; i < ac && kp1 == 0; i++) {
1891 MinusStep(kp1, s, Placev(a)[i], int0, kp1){ BIntD r_ = (BIntD)(((a)->placev)[i])+(BIntD)((((((unsigned
long) 1) << ((8 * sizeof(BIntS)))) - 1) - (((int) 0)))
)+(BIntD)(kp1); BIntS k_ = (r_ >= (BIntD) (((unsigned long
) 1) << ((8 * sizeof(BIntS))))); if (k_) r_ -= (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); (s) = r_; (kp1) = k_
; }
;
1892 Placev(r)((r)->placev)[i] = s;
1893 }
1894
1895 if (kp1 == 1 && Beq(r,a)((r) == (a))) goto normalize;
1896
1897 for ( ; i < ac; i++) {
1898 Placev(r)((r)->placev)[i] = Placev(a)((a)->placev)[i];
1899 }
1900
1901 assert(kp1 == 1)do { if (!(kp1 == 1)) _do_assert(("kp1 == 1"),"bigint.c",1901
); } while (0)
;
1902
1903normalize:
1904 for (i = Placec(a)((a)->placec) - 1; i >= 0; i--)
1905 if (Placev(r)((r)->placev)[i] != 0) break;
1906 Placec(r)((r)->placec) = i+1;
1907}
1908
1909/*
1910 * Multiply non-negative integers a and b and place result in preallocated r.
1911 * The result r, cannot be an alias for a or b.
1912 */
1913void
1914iintTimes(BInt r, BInt a, BInt b)
1915{
1916 IInt i, j, ac, bc;
1917 BIntS k, ai, bj;
1918
1919 assert(!IsImmed(a) && !IsImmed(b))do { if (!(!((long)(a) & 1) && !((long)(b) & 1
))) _do_assert(("!IsImmed(a) && !IsImmed(b)"),"bigint.c"
,1919); } while (0)
;
1920 assert(!IsNeg(a) && !IsNeg(b))do { if (!(!((a)->isNeg) && !((b)->isNeg))) _do_assert
(("!IsNeg(a) && !IsNeg(b)"),"bigint.c",1920); } while
(0)
;
1921 assert(!IsImmed(r) && Placea(r) >= Placec(a)+Placec(b))do { if (!(!((long)(r) & 1) && ((r)->placea) >=
((a)->placec)+((b)->placec))) _do_assert(("!IsImmed(r) && Placea(r) >= Placec(a)+Placec(b)"
),"bigint.c",1921); } while (0)
;
1922
1923 ac = Placec(a)((a)->placec);
1924 bc = Placec(b)((b)->placec);
1925
1926 /* Make a be the longer number to minimize loop cost. */
1927 if (ac < bc) {
1928 BInt x;
1929 IInt xc;
1930 x = a; xc = ac;
1931 a = b; ac = bc;
1932 b = x; bc = xc;
1933 }
1934
1935 for (i = 0; i < ac; i++) Placev(r)((r)->placev)[i] = 0;
1936
1937 for (j = 0; j < bc; j++) {
1938 bj = Placev(b)((b)->placev)[j];
1939 k = 0;
1940 if (bj != 0) {
1941 for (i = 0; i < ac; i++) {
1942 ai = Placev(a)((a)->placev)[i];
1943 TimesStep(k, Placev(r)[i+j],{ BIntD t_ = (BIntD)(ai)*(BIntD)(bj)+(BIntD)(((r)->placev)
[i+j])+(BIntD)(k); (((r)->placev)[i+j]) = t_ % (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); (k) = t_ / (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); }
1944 ai, bj, Placev(r)[i+j], k){ BIntD t_ = (BIntD)(ai)*(BIntD)(bj)+(BIntD)(((r)->placev)
[i+j])+(BIntD)(k); (((r)->placev)[i+j]) = t_ % (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); (k) = t_ / (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); }
;
1945 }
1946 }
1947 Placev(r)((r)->placev)[ac+j] = k;
1948 }
1949 while (Placec(r)((r)->placec) > 0 && Placev(r)((r)->placev)[Placec(r)((r)->placec)-1] == 0) Placec(r)((r)->placec)--;
1950}
1951
1952
1953/*
1954 * Divide the non-negative numbers a and b and place the quotient and
1955 * remainder in the preallocated structures q and r.
1956 *
1957 * The output structure, q, must have space for m+1 digits.
1958 * The output structure, r, must have space for n+m+1 digits
1959 * (unless n = 1 or a < b), even though at most n will be used for output.
1960 *
1961 * The output q may not be an alias for an input.
1962 * The output r can be an alias for the input a.
1963 *
1964 * This is Algorithm D of Knuth Vol 2, Section 4.3.1.
1965 * Note: we index the digits n-1..0 rather than 1..n.
1966 */
1967
1968/*
1969 * Convert to Knuth's notation.
1970 */
1971#define KtoI(ki)(n - (ki)) (n - (ki))
1972#define KtoJu(kj)(nm - (kj)) (nm - (kj))
1973#define KtoJq(kj)(m - (kj)) (m - (kj))
1974#define DB /*Debug*/
1975
1976void
1977iintDivide(BInt q, BInt r, BInt u, BInt v)
1978{
1979 IInt n, m, nm;
1980 IInt i;
1981 IInt ki, kj, kjj; /* Knuths i + j. */
1982 BIntS d, qhat, rhat;
1983 BIntS v1, v2, uj0, uj1, uj2; /* Knuth's v1,v2, uj,uj+1,uj+2 */
1984 BIntS k, kk, vi, ujj, uh, ul;
1985
1986 assert(!IsImmed(u) && !IsImmed(v))do { if (!(!((long)(u) & 1) && !((long)(v) & 1
))) _do_assert(("!IsImmed(u) && !IsImmed(v)"),"bigint.c"
,1986); } while (0)
;
1987 assert(!IsImmed(q) && !IsImmed(r))do { if (!(!((long)(q) & 1) && !((long)(r) & 1
))) _do_assert(("!IsImmed(q) && !IsImmed(r)"),"bigint.c"
,1987); } while (0)
;
1988 assert(Placea(r) > Placec(u))do { if (!(((r)->placea) > ((u)->placec))) _do_assert
(("Placea(r) > Placec(u)"),"bigint.c",1988); } while (0)
;
1989 assert(Placev(v)[Placec(v)-1] != 0)do { if (!(((v)->placev)[((v)->placec)-1] != 0)) _do_assert
(("Placev(v)[Placec(v)-1] != 0"),"bigint.c",1989); } while (0
)
;
1990 assert(q != r && q != u && q != v && r != v)do { if (!(q != r && q != u && q != v &&
r != v)) _do_assert(("q != r && q != u && q != v && r != v"
),"bigint.c",1990); } while (0)
;
1991
1992 n = Placec(v)((v)->placec);
1993 m = Placec(u)((u)->placec) - n;
1994 nm = n + m;
1995
1996 /* Copy u into r as an in-place work area. */
1997 if (r != u) {
1998 for (i = 0; i < nm; i++) Placev(r)((r)->placev)[i] = Placev(u)((u)->placev)[i];
1999 Placec(r)((r)->placec) = nm;
2000 u = r;
2001 }
2002
2003 /* Trivial case: v has 1 digit. */
2004 if (n == 1) {
2005 iintDivideS(q, &rhat, u, Placev(v)((v)->placev)[0]);
2006 Placev(u)((u)->placev)[0] = rhat;
2007 Placec(u)((u)->placec) = 1;
2008 return;
2009 }
2010
2011 /* Trivial case: u < v => q = 0, r = u. */
2012 if (bintLT(u,v)) {
2013 Placec(q)((q)->placec) = 0;
2014 return;
2015 }
2016
2017 /*
2018 * D1. Normalize: choose d which results in v[n-1] >= BINT_RADIX/2.
2019 */
2020 v1= Placev(v)((v)->placev)[KtoI(1)(n - (1))];
2021 if (v1 >= BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS))))/2) {
2022 bintDEBUGif (!((int) 0)) { } else fprintf(dbOut, "**** d = 1 ****\n");
2023 d = 1;
2024 }
2025 else {
2026 d = BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS))))/(v1 + 1);
2027 iintTimesS(u, u, d);
2028 iintTimesS(v, v, d); /* Guaranteed ptr u != v */
2029 }
2030 v1= Placev(v)((v)->placev)[KtoI(1)(n - (1))];
2031 v2= Placev(v)((v)->placev)[KtoI(2)(n - (2))];
2032 if (Placec(u)((u)->placec) == nm) {
2033 Placev(u)((u)->placev)[Placec(u)((u)->placec)++] = 0;
2034 }
2035 assert(Placec(u) == nm+1)do { if (!(((u)->placec) == nm+1)) _do_assert(("Placec(u) == nm+1"
),"bigint.c",2035); } while (0)
;
2036 assert(Placec(v) == n)do { if (!(((v)->placec) == n)) _do_assert(("Placec(v) == n"
),"bigint.c",2036); } while (0)
;
2037
2038 /*
2039 * D2-D7. Each iter, divide u[kj..kj+n] by v[1..n] to get a digit of q.
2040 */
2041 for (kj = 0; kj <= m; kj++) {
2042 /*
2043 * D3. Compute qhat.
2044 */
2045 uj0 = Placev(u)((u)->placev)[KtoJu(kj)(nm - (kj))];
2046 uj1 = Placev(u)((u)->placev)[KtoJu(kj+1)(nm - (kj+1))];
2047 uj2 = Placev(u)((u)->placev)[KtoJu(kj+2)(nm - (kj+2))];
2048
2049 if (uj0 == v1) {
2050 bintDEBUGif (!((int) 0)) { } else fprintf(dbOut, "**** uj0 == v1 ****\n");
2051 qhat = BINT_RADIX_MINUS_1((((unsigned long) 1) << ((8 * sizeof(BIntS)))) - 1);
2052 rhat = uj1;
2053 PlusStep(k, rhat, rhat, v1, int0){ BIntD r_ = (BIntD)(rhat)+(BIntD)(v1)+(BIntD)(((int) 0)); BIntS
k_ = (r_ >= (BIntD) (((unsigned long) 1) << ((8 * sizeof
(BIntS))))); if (k_) r_ -= (((unsigned long) 1) << ((8 *
sizeof(BIntS)))); (rhat) = r_; (k) = k_; }
;
2054
2055 }
2056 else {
2057 DivideDouble(qhat, rhat, uj0, uj1, v1){ BIntD n_ = (BIntD)(uj0)*(BIntD)(((unsigned long) 1) <<
((8 * sizeof(BIntS)))) + (uj1); BIntD d_ = (v1); (qhat) = n_
/ d_; (rhat) = n_ % d_; }
;
2058 k = 0;
2059 }
2060 if (!k) {
2061 BIntS v2qhh, v2qhl;
2062 Bool isGT;
2063 for (i = 1; ; i++) {
2064 /* Loop shd be evaluated no more than twice. */
2065 if (DEBUG(bint)((int) 0)) {
2066 if (i == 2)
2067 fprintf(dbOut, "**** 2 ****\n");
2068 }
2069 assert(i <= 2)do { if (!(i <= 2)) _do_assert(("i <= 2"),"bigint.c",2069
); } while (0)
;
2070 /*
2071 * This test could be speeded up by doing
2072 * unsigned long arithmetic and a comparison
2073 * when BINT_LG_RADIX <= bitsizeof(long).
2074 * However by writing it this way, this code
2075 * could handle a long-sized radix.
2076 */
2077 TimesDouble (v2qhh,v2qhl, v2, qhat){ BIntD t_ = (BIntD)(v2)*(BIntD)(qhat); (v2qhh) = t_ / (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); (v2qhl) = t_ % (((
unsigned long) 1) << ((8 * sizeof(BIntS)))); }
;
2078 TestGTDouble(isGT, v2qhh,v2qhl, rhat,uj2){ BIntS h1_ = (v2qhh), h2_ = (rhat); (isGT) = (h1_ > h2_) ||
(h1_ == h2_ && (v2qhl)>(uj2)); }
;
2079
2080 if (!isGT) break;
2081
2082 qhat--;
2083 PlusStep(k, rhat, rhat, v1, int0){ BIntD r_ = (BIntD)(rhat)+(BIntD)(v1)+(BIntD)(((int) 0)); BIntS
k_ = (r_ >= (BIntD) (((unsigned long) 1) << ((8 * sizeof
(BIntS))))); if (k_) r_ -= (((unsigned long) 1) << ((8 *
sizeof(BIntS)))); (rhat) = r_; (k) = k_; }
;
2084 if (k) break;
2085 }
2086 }
2087 if (DEBUG(bint)((int) 0)) {
2088 if (k)
2089 fprintf(dbOut, "**** rhat ov ****\n");
2090 }
2091
2092 /*
2093 * D4. Multiply and subtract: u[kj..kj+n] -= qhat * (0,v[1..n])
2094 */
2095
2096 k = 0;
2097
2098 for (ki = n, kjj = kj+n; ki >= 0; ki--, kjj--) {
2099 vi = (ki == 0) ? 0 : Placev(v)((v)->placev)[KtoI(ki)(n - (ki))];
2100 ujj = Placev(u)((u)->placev)[KtoJu(kjj)(nm - (kjj))];
2101
2102 TimesDouble(uh, ul, qhat, vi){ BIntD t_ = (BIntD)(qhat)*(BIntD)(vi); (uh) = t_ / (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); (ul) = t_ % (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); }
;
2103
2104 MinusStep(kk, ujj, ujj, ul, 1){ BIntD r_ = (BIntD)(ujj)+(BIntD)((((((unsigned long) 1) <<
((8 * sizeof(BIntS)))) - 1) - (ul)))+(BIntD)(1); BIntS k_ = (
r_ >= (BIntD) (((unsigned long) 1) << ((8 * sizeof(BIntS
))))); if (k_) r_ -= (((unsigned long) 1) << ((8 * sizeof
(BIntS)))); (ujj) = r_; (kk) = k_; }
;
2105 uh += !kk;
2106
2107 MinusStep(kk, ujj, ujj, k, 1){ BIntD r_ = (BIntD)(ujj)+(BIntD)((((((unsigned long) 1) <<
((8 * sizeof(BIntS)))) - 1) - (k)))+(BIntD)(1); BIntS k_ = (
r_ >= (BIntD) (((unsigned long) 1) << ((8 * sizeof(BIntS
))))); if (k_) r_ -= (((unsigned long) 1) << ((8 * sizeof
(BIntS)))); (ujj) = r_; (kk) = k_; }
;
2108 uh += !kk;
2109
2110 Placev(u)((u)->placev)[KtoJu(kjj)(nm - (kjj))] = ujj;
2111 k = uh;
2112 }
2113
2114 /*
2115 * D5. Set quotient digit and test remainder.
2116 */
2117 Placev(q)((q)->placev)[KtoJq(kj)(m - (kj))] = qhat; /* I.e. Knuth's q[j] */
2118
2119 if (k != 0) {
2120 /*
2121 * D6. Add back: u[kj..kj+n] += (0,v[1..n])
2122 */
2123 bintDEBUGif (!((int) 0)) { } else fprintf(dbOut, "**** Add Back %d ****\n", k);
2124 Placev(q)((q)->placev)[KtoJq(kj)(m - (kj))]--;
2125 k = 0;
2126
2127 for (ki = n, kjj = kj+n; ki >= 0; ki--, kjj--) {
2128 vi = (ki == 0) ? 0 : Placev(v)((v)->placev)[KtoI(ki)(n - (ki))];
2129
2130 PlusStep(k, Placev(u)[KtoJu(kjj)],{ BIntD r_ = (BIntD)(vi)+(BIntD)(((u)->placev)[(nm - (kjj)
)])+(BIntD)(k); BIntS k_ = (r_ >= (BIntD) (((unsigned long
) 1) << ((8 * sizeof(BIntS))))); if (k_) r_ -= (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); (((u)->placev)[
(nm - (kjj))]) = r_; (k) = k_; }
2131 vi, Placev(u)[KtoJu(kjj)], k){ BIntD r_ = (BIntD)(vi)+(BIntD)(((u)->placev)[(nm - (kjj)
)])+(BIntD)(k); BIntS k_ = (r_ >= (BIntD) (((unsigned long
) 1) << ((8 * sizeof(BIntS))))); if (k_) r_ -= (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); (((u)->placev)[
(nm - (kjj))]) = r_; (k) = k_; }
;
2132 }
2133 }
2134 }
2135
2136 /*
2137 * D8. Unnormalize: u /= d
2138 */
2139 Placec(u)((u)->placec) = n;
2140 iintDivideS(u, NULL((void*)0), u, d);
2141 iintDivideS(v, NULL((void*)0), v, d); /* Return v to original state. */
2142
2143 /* Set place counts to not see leading zeros. */
2144 for (i = Placec(q)((q)->placec)-1; i >= 0; i--)
2145 if (Placev(q)((q)->placev)[i] != 0) break;
2146 Placec(q)((q)->placec) = i+1;
2147
2148 for (i = Placec(u)((u)->placec)-1; i >= 0; i--)
2149 if (Placev(u)((u)->placev)[i] != 0) break;
2150 Placec(u)((u)->placec) = i+1;
2151}
2152
2153/*
2154 * iintShift(r, b, n)
2155 * Shift b by n bits into r;
2156 * The result, r, can be an alias for the argument b.
2157 *
2158 * Examples:
2159 * BINT_LG_RADIX = 4
2160 * n -- number of bits shifted by
2161 * bitc -- bit count of result
2162 * c -- number of places
2163 * z -- number of zero bits in leading place
2164 * up -- whether position of bits in first place is further up
2165 * q -- upward rel offset of first place (not including chopped zeros)
2166 * q0 -- upward rel offset of first place (including phantom chopped zeros)
2167 * h -- upward rel offset of bits from previous place
2168 * k -- downard rel offset of bits within place
2169 *
2170 * n bitc c z up q q0 h k
2171 * .ooaa.bbbb.0000.0000. 8 14 4 2 n 2 2 4 0
2172 * .0ooa.abbb.b000.0000. 7 13 4 3 n 2 2 3 1
2173 * .aabb.bb00.0000. 6 12 3 0 y 1 2 2 2
2174 * .oaab.bbb0.0000. 5 11 3 1 y 1 2 1 3
2175 * .ooaa.bbbb.0000. 4 10 3 2 n 1 1 4 0
2176 * .0ooa.abbb.b000. 3 9 3 3 n 1 1 3 1
2177 * .aabb.bb00. 2 8 2 0 y 0 1 2 2
2178 * .oaab.bbb0. 1 7 2 1 y 0 1 1 3
2179 * .ooaa.bbbb. 0 6 2 2 n 0 0 4 0
2180 * .0ooa.abbb. -1 5 2 3 n 0 0 3 1
2181 * .aabb. -2 4 1 0 y -1 0 1 2
2182 * .oaab. -3 3 1 1 y -1 0 3 1
2183 * .ooaa. -4 2 1 2 n -1 -1 4 0
2184 * .0ooa. -5 1 1 3 n -1 -1 3 1
2185 * . -6 0 0 0 y -2 -1 2 2
2186 */
2187
2188void
2189iintShift(BInt r, BInt b, int n)
2190{
2191 IInt q, q0, h, k;
2192 IInt rbitc, rc, rz;
2193 IInt bbitc, bc, bz;
2194 Bool up;
2195 IInt i, j, x0, x1;
2196 BIntS *rp, *bp;
2197
2198 assert(!IsImmed(r) && !IsImmed(b))do { if (!(!((long)(r) & 1) && !((long)(b) & 1
))) _do_assert(("!IsImmed(r) && !IsImmed(b)"),"bigint.c"
,2198); } while (0)
;
8
Assuming the condition is false
9
Taking true branch
10
Loop condition is false. Exiting loop
2199
2200 bbitc = bintLength(b);
2201 bc = Placec(b)((b)->placec);
2202 bz = bc * BINT_LG_RADIX((8 * sizeof(BIntS))) - bbitc;
2203 bp = Placev(b)((b)->placev);
2204
2205 rbitc = bbitc + n;
2206 rc = QUO_ROUND_UP(rbitc, BINT_LG_RADIX)((rbitc) % (((8 * sizeof(BIntS)))) ? (rbitc)/(((8 * sizeof(BIntS
)))) + 1 : (rbitc)/(((8 * sizeof(BIntS)))))
;
11
Assuming the condition is false
12
'?' condition is false
2207 rz = rc * BINT_LG_RADIX((8 * sizeof(BIntS))) - rbitc;
2208 rp = Placev(r)((r)->placev);
2209
2210 assert(Placea(r) >= rc)do { if (!(((r)->placea) >= rc)) _do_assert(("Placea(r) >= rc"
),"bigint.c",2210); } while (0)
;
13
Assuming 'rc' is <= field 'placea'
14
Taking false branch
15
Loop condition is false. Exiting loop
2211 Placec(r)((r)->placec) = rc;
2212 IsNeg(r)((r)->isNeg) = IsNeg(b)((b)->isNeg);
2213
2214 up = (rz <= bz);
16
Assuming 'rz' is > 'bz'
2215 q = rc - bc;
2216 q0 = q + up;
2217 h = q0 * BINT_LG_RADIX((8 * sizeof(BIntS))) - n;
2218 k = BINT_LG_RADIX((8 * sizeof(BIntS))) - h;
17
Value assigned to 'k'
2219 x0 = 0; /* for lint */
2220
2221 /*
2222 * Copy in the direction which allows in-place operation.
2223 *
2224 * Each place's value is temporarily held in x0 until
2225 * it is certain that the original value of that place
2226 * will not be needed.
2227 */
2228
2229 /*
2230 * Would you believe that some compiler have trouble with x<<32
2231 * MIPS cc on IRIX64 with -64
2232 */
2233 if (h == BINT_LG_RADIX((8 * sizeof(BIntS)))) h=0;
18
Assuming the condition is false
19
Taking false branch
2234 if (n < 0) {
20
Assuming 'n' is < 0
21
Taking true branch
2235 /* Copy from lo to hi. */
2236 bp -= q0;
2237 i = 0;
2238 j = 0;
2239
2240 if (rc > 1) {
22
Assuming 'rc' is > 1
2241 x0 = h ? bp[i] >> h : 0;
23
Taking true branch
24
Assuming 'h' is 0
25
'?' condition is false
2242 x0 |= bp[++i] << k;
26
The result of left shift is undefined because the right operand is >= 32, not smaller than 32, the capacity of 'BIntS'
2243 }
2244 while (i < rc-1) {
2245 x1 = x0;
2246 x0 = h ? bp[i] >> h : 0 ;
2247 x0 |= bp[++i] << k;
2248
2249 rp[j++] = x1 & BINT_RADIX_MASK((((unsigned long) 1) << ((8 * sizeof(BIntS)))) - 1);
2250 }
2251 if (rc > 1)
2252 rp[j++] = x0 & BINT_RADIX_MASK((((unsigned long) 1) << ((8 * sizeof(BIntS)))) - 1);
2253 if (up) {
2254 x0 = h ? bp[i] >> h : 0;
2255 x0 |= bp[++i] << k;
2256 }
2257 else {
2258 x0 = h ? bp[i] >> h : 0;
2259 }
2260 rp[j++] = x0 & BINT_RADIX_MASK((((unsigned long) 1) << ((8 * sizeof(BIntS)))) - 1);
2261 }
2262 else if (n > 0) {
2263 /* Copy from hi to lo. */
2264 i = bc - 1;
2265 j = rc - 1;
2266
2267 if (up) {
2268 x0 = bp[i--] << k;
2269 x0 |= h ? bp[i] >> h : 0;
2270 }
2271 else {
2272 x0 = h ? bp[i] >> h : 0;
2273 }
2274 while (i > 0) {
2275 x1 = x0;
2276 x0 = bp[i--] << k;
2277 x0 |= h ? bp[i] >> h : 0;
2278
2279 rp[j--] = x1 & BINT_RADIX_MASK((((unsigned long) 1) << ((8 * sizeof(BIntS)))) - 1);
2280 }
2281 if (i == 0) {
2282 x1 = x0;
2283 x0 = bp[0] << k;
2284 rp[j--] = x1 & BINT_RADIX_MASK((((unsigned long) 1) << ((8 * sizeof(BIntS)))) - 1);
2285 }
2286 rp[j--] = x0 & BINT_RADIX_MASK((((unsigned long) 1) << ((8 * sizeof(BIntS)))) - 1);
2287
2288 while (j >= 0) rp[j--] = 0;
2289 }
2290 else /* n == 0 */ {
2291 for (i = 0; i < rc; i++) rp[i] = bp[i];
2292 }
2293}
2294
2295/*
2296 * iintTimesS(r, a, b)
2297 *
2298 * Place the value a*b into r.
2299 * The result, r, can be an alias for the input a.
2300 */
2301void
2302iintTimesS(BInt r, BInt a, BIntS b)
2303{
2304 IInt n, j;
2305 BIntS c;
2306
2307 assert(!IsImmed(r) && !IsImmed(a))do { if (!(!((long)(r) & 1) && !((long)(a) & 1
))) _do_assert(("!IsImmed(r) && !IsImmed(a)"),"bigint.c"
,2307); } while (0)
;
2308 assert(Placea(r) >= Placea(a))do { if (!(((r)->placea) >= ((a)->placea))) _do_assert
(("Placea(r) >= Placea(a)"),"bigint.c",2308); } while (0)
;
2309
2310 /* !!! xintCopyInI may reallocate */
2311 if (b == 0) { xintCopyInI(r, int0((int) 0)); return; }
2312
2313 n = Placec(a)((a)->placec);
2314 c = 0;
2315
2316 for (j = 0; j < n; j++)
2317 TimesStep(c, Placev(r)[j], Placev(a)[j], b, c, int0){ BIntD t_ = (BIntD)(((a)->placev)[j])*(BIntD)(b)+(BIntD)(
c)+(BIntD)(((int) 0)); (((r)->placev)[j]) = t_ % (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); (c) = t_ / (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); }
;
2318
2319 if (c) Placev(r)((r)->placev)[j++] = c;
2320 Placec(r)((r)->placec) = j;
2321}
2322
2323/*
2324 * iintTimesPlusS(r, a, b, c)
2325 *
2326 * Place the value a*b + c into r.
2327 * The result, r, can be an alias for the input a.
2328 */
2329void
2330iintTimesPlusS(BInt r, BInt a, BIntS b, BIntS c)
2331{
2332 IInt n, j;
2333
2334 assert(!IsImmed(r) && !IsImmed(a))do { if (!(!((long)(r) & 1) && !((long)(a) & 1
))) _do_assert(("!IsImmed(r) && !IsImmed(a)"),"bigint.c"
,2334); } while (0)
;
2335 assert(Placea(r) >= Placea(a))do { if (!(((r)->placea) >= ((a)->placea))) _do_assert
(("Placea(r) >= Placea(a)"),"bigint.c",2335); } while (0)
;
2336
2337 /* !!! xintCopyInI may reallocate */
2338 if (b == 0) { xintCopyInI(r, c); return; }
2339
2340 n = Placec(a)((a)->placec);
2341
2342 for (j = 0; j < n; j++)
2343 TimesStep(c, Placev(r)[j], Placev(a)[j], b, c, int0){ BIntD t_ = (BIntD)(((a)->placev)[j])*(BIntD)(b)+(BIntD)(
c)+(BIntD)(((int) 0)); (((r)->placev)[j]) = t_ % (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); (c) = t_ / (((unsigned
long) 1) << ((8 * sizeof(BIntS)))); }
;
2344
2345 if (c) Placev(r)((r)->placev)[j++] = c;
2346 Placec(r)((r)->placec) = j;
2347}
2348
2349/*
2350 * iintDivideS(q, &r, a, b)
2351 *
2352 * This divides the positive multiprecision number a by the half precision
2353 * number b, 0 < b < BINT_RADIX.
2354 *
2355 * The quotient is placed in q and the remainder in r.
2356 * If q == u, then the operation is done in-place.
2357 *
2358 * The result, q, can be an alias for a.
2359 */
2360void
2361iintDivideS(BInt q, BIntS *pr, BInt a, BIntS b)
2362{
2363 IInt n, j;
2364 BIntS r;
2365
2366 assert(!IsImmed(q) && !IsImmed(a))do { if (!(!((long)(q) & 1) && !((long)(a) & 1
))) _do_assert(("!IsImmed(q) && !IsImmed(a)"),"bigint.c"
,2366); } while (0)
;
2367#ifndef BIGINT_SHHHH
2368 if (Placea(q)((q)->placea) < Placec(a)((a)->placec))
2369 printf("This is it guys.\n");
2370#endif
2371 assert(Placea(q) >= Placec(a))do { if (!(((q)->placea) >= ((a)->placec))) _do_assert
(("Placea(q) >= Placec(a)"),"bigint.c",2371); } while (0)
;
2372
2373 n = Placec(a)((a)->placec);
2374 r = 0;
2375 for (j = n-1; j >= 0; j--)
2376 DivideDouble(Placev(q)[j], r, r, Placev(a)[j], b){ BIntD n_ = (BIntD)(r)*(BIntD)(((unsigned long) 1) << (
(8 * sizeof(BIntS)))) + (((a)->placev)[j]); BIntD d_ = (b)
; (((q)->placev)[j]) = n_ / d_; (r) = n_ % d_; }
;
2377
2378 Placec(q)((q)->placec) = (Placev(q)((q)->placev)[n-1] == 0) ? n-1 : n;
2379 if (pr) *pr = r;
2380}
2381