blob: b21738de6e005ffd1386b645cb4b80277f49c8dd [file] [log] [blame]
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Long (arbitrary precision) integer object implementation */
26
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000027/* XXX The functional organization of this file is terrible */
28
Guido van Rossumedcc38a1991-05-05 20:09:44 +000029#include "allobjects.h"
30#include "longintrepr.h"
Guido van Rossum149e9ea1991-06-03 10:58:24 +000031#include <math.h>
Guido van Rossumedcc38a1991-05-05 20:09:44 +000032#include <assert.h>
33
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000034static int ticker; /* XXX Could be shared with ceval? */
35
Guido van Rossumc6913e71991-11-19 20:26:46 +000036#define ZABS(x) ((x) < 0 ? ~(x) : (x))
37
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000038#define INTRCHECK(block) \
39 if (--ticker < 0) { \
40 ticker = 100; \
41 if (intrcheck()) { block; } \
42 }
43
Guido van Rossumedcc38a1991-05-05 20:09:44 +000044/* Normalize (remove leading zeros from) a long int object.
45 Doesn't attempt to free the storage--in most cases, due to the nature
46 of the algorithms used, this could save at most be one word anyway. */
47
48longobject *
49long_normalize(v)
50 register longobject *v;
51{
Guido van Rossumc6913e71991-11-19 20:26:46 +000052 int j = ZABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +000053 register int i = j;
54
55 while (i > 0 && v->ob_digit[i-1] == 0)
56 --i;
57 if (i != j)
Guido van Rossumc6913e71991-11-19 20:26:46 +000058 v->ob_size = (v->ob_size < 0) ? ~i : i;
59 if (v->ob_size == ~0)
60 v->ob_size = 0;
61 return v;
62}
63
64/* Normalize except leave ~0 unchanged */
65
66longobject *
67long_znormalize(v)
68 register longobject *v;
69{
70 int j = ZABS(v->ob_size);
71 register int i = j;
72
73 while (i > 0 && v->ob_digit[i-1] == 0)
74 --i;
75 if (i != j)
76 v->ob_size = (v->ob_size < 0) ? ~i : i;
Guido van Rossumedcc38a1991-05-05 20:09:44 +000077 return v;
78}
79
80/* Allocate a new long int object with size digits.
81 Return NULL and set exception if we run out of memory. */
82
83longobject *
84alloclongobject(size)
85 int size;
86{
87 return NEWVAROBJ(longobject, &Longtype, size);
88}
89
90/* Create a new long int object from a C long int */
91
92object *
93newlongobject(ival)
94 long ival;
95{
96 /* Assume a C long fits in at most 3 'digits' */
97 longobject *v = alloclongobject(3);
98 if (v != NULL) {
99 if (ival < 0) {
100 ival = -ival;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000101 v->ob_size = ~v->ob_size;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000102 }
103 v->ob_digit[0] = ival & MASK;
104 v->ob_digit[1] = (ival >> SHIFT) & MASK;
105 v->ob_digit[2] = (ival >> (2*SHIFT)) & MASK;
106 v = long_normalize(v);
107 }
108 return (object *)v;
109}
110
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000111/* Create a new long int object from a C double */
112
113object *
114dnewlongobject(dval)
115 double dval;
116{
117 longobject *v;
118 double frac;
119 int i, ndig, expo, neg;
120 neg = 0;
121 if (dval < 0.0) {
122 neg = 1;
123 dval = -dval;
124 }
125 frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
126 if (expo <= 0)
127 return newlongobject(0L);
128 ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
129 v = alloclongobject(ndig);
130 if (v == NULL)
131 return NULL;
132 frac = ldexp(frac, (expo-1) % SHIFT + 1);
133 for (i = ndig; --i >= 0; ) {
134 long bits = (long)frac;
135 v->ob_digit[i] = bits;
136 frac = frac - (double)bits;
137 frac = ldexp(frac, SHIFT);
138 }
139 if (neg)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000140 v->ob_size = ~v->ob_size;
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000141 return (object *)v;
142}
143
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000144/* Get a C long int from a long int object.
145 Returns -1 and sets an error condition if overflow occurs. */
146
147long
148getlongvalue(vv)
149 object *vv;
150{
151 register longobject *v;
152 long x, prev;
153 int i, sign;
154
155 if (vv == NULL || !is_longobject(vv)) {
156 err_badcall();
157 return -1;
158 }
159 v = (longobject *)vv;
160 i = v->ob_size;
161 sign = 1;
162 x = 0;
163 if (i < 0) {
164 sign = -1;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000165 i = ~i;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000166 }
167 while (--i >= 0) {
168 prev = x;
169 x = (x << SHIFT) + v->ob_digit[i];
170 if ((x >> SHIFT) != prev) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000171 err_setstr(ValueError,
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000172 "long int too long to convert");
173 return -1;
174 }
175 }
176 return x * sign;
177}
178
179/* Get a C double from a long int object. No overflow check. */
180
181double
182dgetlongvalue(vv)
183 object *vv;
184{
185 register longobject *v;
186 double x;
187 double multiplier = (double) (1L << SHIFT);
188 int i, sign;
189
190 if (vv == NULL || !is_longobject(vv)) {
191 err_badcall();
192 return -1;
193 }
194 v = (longobject *)vv;
195 i = v->ob_size;
196 sign = 1;
197 x = 0.0;
198 if (i < 0) {
199 sign = -1;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000200 i = ~i;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000201 }
202 while (--i >= 0) {
203 x = x*multiplier + v->ob_digit[i];
204 }
205 return x * sign;
206}
207
208/* Multiply by a single digit, ignoring the sign. */
209
210longobject *
211mul1(a, n)
212 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000213 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000214{
215 return muladd1(a, n, (digit)0);
216}
217
218/* Multiply by a single digit and add a single digit, ignoring the sign. */
219
220longobject *
221muladd1(a, n, extra)
222 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000223 wdigit n;
224 wdigit extra;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000225{
Guido van Rossumc6913e71991-11-19 20:26:46 +0000226 int size_a = ZABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000227 longobject *z = alloclongobject(size_a+1);
228 twodigits carry = extra;
229 int i;
230
231 if (z == NULL)
232 return NULL;
233 for (i = 0; i < size_a; ++i) {
234 carry += (twodigits)a->ob_digit[i] * n;
235 z->ob_digit[i] = carry & MASK;
236 carry >>= SHIFT;
237 }
238 z->ob_digit[i] = carry;
239 return long_normalize(z);
240}
241
242/* Divide a long integer by a digit, returning both the quotient
243 (as function result) and the remainder (through *prem).
244 The sign of a is ignored; n should not be zero. */
245
246longobject *
247divrem1(a, n, prem)
248 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000249 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000250 digit *prem;
251{
Guido van Rossumc6913e71991-11-19 20:26:46 +0000252 int size = ZABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000253 longobject *z;
254 int i;
255 twodigits rem = 0;
256
257 assert(n > 0 && n <= MASK);
258 z = alloclongobject(size);
259 if (z == NULL)
260 return NULL;
261 for (i = size; --i >= 0; ) {
262 rem = (rem << SHIFT) + a->ob_digit[i];
263 z->ob_digit[i] = rem/n;
264 rem %= n;
265 }
266 *prem = rem;
267 return long_normalize(z);
268}
269
270/* Convert a long int object to a string, using a given conversion base.
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000271 Return a string object.
272 If base is 8 or 16, add the proper prefix '0' or '0x'. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000273
274stringobject *
275long_format(a, base)
276 longobject *a;
277 int base;
278{
279 stringobject *str;
280 int i;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000281 int size_a = ZABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000282 char *p;
283 int bits;
284 char sign = '\0';
285
286 assert(base >= 2 && base <= 36);
287
288 /* Compute a rough upper bound for the length of the string */
289 i = base;
290 bits = 0;
291 while (i > 1) {
292 ++bits;
293 i >>= 1;
294 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000295 i = 6 + (size_a*SHIFT + bits-1) / bits;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000296 str = (stringobject *) newsizedstringobject((char *)0, i);
297 if (str == NULL)
298 return NULL;
299 p = GETSTRINGVALUE(str) + i;
300 *p = '\0';
Guido van Rossumc6913e71991-11-19 20:26:46 +0000301 *--p = 'L';
302 if (a->ob_size < 0) {
303 if (a->ob_size < ~0)
304 sign = '-';
305 else
306 sign = '~';
307 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000308
309 INCREF(a);
310 do {
311 digit rem;
312 longobject *temp = divrem1(a, (digit)base, &rem);
313 if (temp == NULL) {
314 DECREF(a);
315 DECREF(str);
316 return NULL;
317 }
318 if (rem < 10)
319 rem += '0';
320 else
321 rem += 'A'-10;
322 assert(p > GETSTRINGVALUE(str));
323 *--p = rem;
324 DECREF(a);
325 a = temp;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000326 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000327 DECREF(a);
328 DECREF(str);
329 err_set(KeyboardInterrupt);
330 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000331 })
Guido van Rossumc6913e71991-11-19 20:26:46 +0000332 } while (ZABS(a->ob_size) != 0);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000333 DECREF(a);
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000334 if (base == 8)
335 *--p = '0';
336 else if (base == 16) {
337 *--p = 'x';
338 *--p = '0';
339 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000340 else if (base != 10) {
341 *--p = '#';
342 *--p = '0' + base%10;
343 if (base > 10)
344 *--p = '0' + base/10;
345 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000346 if (sign)
347 *--p = sign;
348 if (p != GETSTRINGVALUE(str)) {
349 char *q = GETSTRINGVALUE(str);
350 assert(p > q);
351 do {
352 } while ((*q++ = *p++) != '\0');
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000353 q--;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000354 resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
355 }
356 return str;
357}
358
359/* Convert a string to a long int object, in a given base.
360 Base zero implies a default depending on the number. */
361
362object *
363long_scan(str, base)
364 char *str;
365 int base;
366{
367 int sign = 1;
368 longobject *z;
369
370 assert(base == 0 || base >= 2 && base <= 36);
371 if (*str == '+')
372 ++str;
373 else if (*str == '-') {
374 ++str;
375 sign = -1;
376 }
377 if (base == 0) {
378 if (str[0] != '0')
379 base = 10;
380 else if (str[1] == 'x' || str[1] == 'X')
381 base = 16;
382 else
383 base = 8;
384 }
385 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
386 str += 2;
387 z = alloclongobject(0);
388 for ( ; z != NULL; ++str) {
389 int k = -1;
390 longobject *temp;
391
392 if (*str <= '9')
393 k = *str - '0';
394 else if (*str >= 'a')
395 k = *str - 'a' + 10;
396 else if (*str >= 'A')
397 k = *str - 'A' + 10;
398 if (k < 0 || k >= base)
399 break;
400 temp = muladd1(z, (digit)base, (digit)k);
401 DECREF(z);
402 z = temp;
403 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000404 if (sign < 0 && z != NULL && z->ob_size != 0)
405 z->ob_size = ~z->ob_size;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000406 return (object *) z;
407}
408
409static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
Guido van Rossumc6913e71991-11-19 20:26:46 +0000410static object *long_pos PROTO((longobject *));
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000411
412/* Long division with remainder, top-level routine */
413
414longobject *
415long_divrem(a, b, prem)
416 longobject *a, *b;
417 longobject **prem;
418{
Guido van Rossumc6913e71991-11-19 20:26:46 +0000419 int size_a = ZABS(a->ob_size), size_b = ZABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000420 longobject *z;
421
422 if (size_b == 0) {
423 if (prem != NULL)
424 *prem = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000425 err_setstr(ZeroDivisionError, "long division or remainder");
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000426 return NULL;
427 }
428 if (size_a < size_b ||
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000429 size_a == size_b &&
430 a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000431 /* |a| < |b|. */
432 if (prem != NULL) {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000433 object *long_pos();
434 *prem = (longobject *) long_pos(a);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000435 }
436 return alloclongobject(0);
437 }
438 if (size_b == 1) {
439 digit rem = 0;
440 z = divrem1(a, b->ob_digit[0], &rem);
441 if (prem != NULL) {
442 if (z == NULL)
443 *prem = NULL;
444 else
445 *prem = (longobject *)
446 newlongobject((long)rem);
447 }
448 }
449 else
450 z = x_divrem(a, b, prem);
451 /* Set the signs.
452 The quotient z has the sign of a*b;
453 the remainder r has the sign of a,
454 so a = b*z + r. */
455 if (z != NULL) {
456 if ((a->ob_size < 0) != (b->ob_size < 0))
Guido van Rossumc6913e71991-11-19 20:26:46 +0000457 z->ob_size = ~ z->ob_size;
458 if (prem != NULL && *prem != NULL && a->ob_size < 0 &&
459 (*prem)->ob_size != 0)
460 (*prem)->ob_size = ~ (*prem)->ob_size;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000461 }
462 return z;
463}
464
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000465/* Unsigned long division with remainder -- the algorithm */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000466
467static longobject *
468x_divrem(v1, w1, prem)
469 longobject *v1, *w1;
470 longobject **prem;
471{
Guido van Rossumc6913e71991-11-19 20:26:46 +0000472 int size_v = ZABS(v1->ob_size), size_w = ZABS(w1->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000473 digit d = (twodigits)BASE / (w1->ob_digit[size_w-1] + 1);
474 longobject *v = mul1(v1, d);
475 longobject *w = mul1(w1, d);
476 longobject *a;
477 int j, k;
478
479 if (v == NULL || w == NULL) {
480 XDECREF(v);
481 XDECREF(w);
482 if (prem != NULL)
483 *prem = NULL;
484 return NULL;
485 }
486
487 assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000488 assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
Guido van Rossumc6913e71991-11-19 20:26:46 +0000489 assert(size_w == ZABS(w->ob_size)); /* That's how d was calculated */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000490
Guido van Rossumc6913e71991-11-19 20:26:46 +0000491 size_v = ZABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000492 a = alloclongobject(size_v - size_w + 1);
493
494 for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
495 digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
496 twodigits q;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000497 stwodigits carry = 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000498 int i;
499
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000500 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000501 DECREF(a);
502 a = NULL;
503 err_set(KeyboardInterrupt);
504 break;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000505 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000506 if (vj == w->ob_digit[size_w-1])
507 q = MASK;
508 else
509 q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
510 w->ob_digit[size_w-1];
511
512 while (w->ob_digit[size_w-2]*q >
513 ((
514 ((twodigits)vj << SHIFT)
515 + v->ob_digit[j-1]
516 - q*w->ob_digit[size_w-1]
517 ) << SHIFT)
518 + v->ob_digit[j-2])
519 --q;
520
521 for (i = 0; i < size_w && i+k < size_v; ++i) {
522 twodigits z = w->ob_digit[i] * q;
523 digit zz = z >> SHIFT;
524 carry += v->ob_digit[i+k] - z + ((twodigits)zz << SHIFT);
525 v->ob_digit[i+k] = carry & MASK;
526 carry = (carry >> SHIFT) - zz;
527 }
528
529 if (i+k < size_v) {
530 carry += v->ob_digit[i+k];
531 v->ob_digit[i+k] = 0;
532 }
533
534 if (carry == 0)
535 a->ob_digit[k] = q;
536 else {
537 assert(carry == -1);
538 a->ob_digit[k] = q-1;
539 carry = 0;
540 for (i = 0; i < size_w && i+k < size_v; ++i) {
541 carry += v->ob_digit[i+k] + w->ob_digit[i];
542 v->ob_digit[i+k] = carry & MASK;
543 carry >>= SHIFT;
544 }
545 }
546 } /* for j, k */
547
Guido van Rossumc6913e71991-11-19 20:26:46 +0000548 if (a == NULL) {
549 if (prem != NULL)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000550 *prem = NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000551 }
552 else {
553 a = long_normalize(a);
554 if (prem != NULL) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000555 *prem = divrem1(v, d, &d);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000556 /* d receives the (unused) remainder */
557 if (*prem == NULL) {
558 DECREF(a);
559 a = NULL;
560 }
561 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000562 }
563 DECREF(v);
564 DECREF(w);
565 return a;
566}
567
568/* Methods */
569
570static void
571long_dealloc(v)
572 longobject *v;
573{
574 DEL(v);
575}
576
Guido van Rossum90933611991-06-07 16:10:43 +0000577static int
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000578long_print(v, fp, flags)
579 longobject *v;
580 FILE *fp;
581 int flags;
582{
583 stringobject *str = long_format(v, 10);
Guido van Rossum90933611991-06-07 16:10:43 +0000584 if (str == NULL)
585 return -1;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000586 fprintf(fp, "%s", GETSTRINGVALUE(str));
Guido van Rossum90933611991-06-07 16:10:43 +0000587 DECREF(str);
588 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000589}
590
591static object *
592long_repr(v)
593 longobject *v;
594{
Guido van Rossumc6913e71991-11-19 20:26:46 +0000595 return (object *) long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000596}
597
598static int
599long_compare(a, b)
600 longobject *a, *b;
601{
602 int sign;
603
Guido van Rossumc6913e71991-11-19 20:26:46 +0000604 if (a->ob_size != b->ob_size) {
605 if (ZABS(a->ob_size) == 0 && ZABS(b->ob_size) == 0)
606 sign = 0;
607 else
608 sign = a->ob_size - b->ob_size;
609 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000610 else {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000611 int i = ZABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000612 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
613 ;
614 if (i < 0)
615 sign = 0;
616 else
617 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
618 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000619 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000620}
621
622/* Add the absolute values of two long integers. */
623
624static longobject *x_add PROTO((longobject *, longobject *));
625static longobject *
626x_add(a, b)
627 longobject *a, *b;
628{
Guido van Rossumc6913e71991-11-19 20:26:46 +0000629 int size_a = ZABS(a->ob_size), size_b = ZABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000630 longobject *z;
631 int i;
632 digit carry = 0;
633
634 /* Ensure a is the larger of the two: */
635 if (size_a < size_b) {
636 { longobject *temp = a; a = b; b = temp; }
637 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
638 }
639 z = alloclongobject(size_a+1);
640 if (z == NULL)
641 return NULL;
642 for (i = 0; i < size_b; ++i) {
643 carry += a->ob_digit[i] + b->ob_digit[i];
644 z->ob_digit[i] = carry & MASK;
645 /* The following assumes unsigned shifts don't
646 propagate the sign bit. */
647 carry >>= SHIFT;
648 }
649 for (; i < size_a; ++i) {
650 carry += a->ob_digit[i];
651 z->ob_digit[i] = carry & MASK;
652 carry >>= SHIFT;
653 }
654 z->ob_digit[i] = carry;
655 return long_normalize(z);
656}
657
658/* Subtract the absolute values of two integers. */
659
660static longobject *x_sub PROTO((longobject *, longobject *));
661static longobject *
662x_sub(a, b)
663 longobject *a, *b;
664{
Guido van Rossumc6913e71991-11-19 20:26:46 +0000665 int size_a = ZABS(a->ob_size), size_b = ZABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000666 longobject *z;
667 int i;
668 int sign = 1;
669 digit borrow = 0;
670
671 /* Ensure a is the larger of the two: */
672 if (size_a < size_b) {
673 sign = -1;
674 { longobject *temp = a; a = b; b = temp; }
675 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
676 }
677 else if (size_a == size_b) {
678 /* Find highest digit where a and b differ: */
679 i = size_a;
680 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
681 ;
682 if (i < 0)
683 return alloclongobject(0);
684 if (a->ob_digit[i] < b->ob_digit[i]) {
685 sign = -1;
686 { longobject *temp = a; a = b; b = temp; }
687 }
688 size_a = size_b = i+1;
689 }
690 z = alloclongobject(size_a);
691 if (z == NULL)
692 return NULL;
693 for (i = 0; i < size_b; ++i) {
694 /* The following assumes unsigned arithmetic
695 works module 2**N for some N>SHIFT. */
696 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
697 z->ob_digit[i] = borrow & MASK;
698 borrow >>= SHIFT;
699 borrow &= 1; /* Keep only one sign bit */
700 }
701 for (; i < size_a; ++i) {
702 borrow = a->ob_digit[i] - borrow;
703 z->ob_digit[i] = borrow & MASK;
704 borrow >>= SHIFT;
705 }
706 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000707 if (sign < 0)
708 z->ob_size = ~z->ob_size;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000709 return long_normalize(z);
710}
711
712static object *
713long_add(a, w)
714 longobject *a;
715 object *w;
716{
717 longobject *b;
718 longobject *z;
719
720 if (!is_longobject(w)) {
721 err_badarg();
722 return NULL;
723 }
724 b = (longobject *)w;
725
726 if (a->ob_size < 0) {
727 if (b->ob_size < 0) {
728 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000729 if (z != NULL && z->ob_size != 0)
730 z->ob_size = ~z->ob_size;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000731 }
732 else
733 z = x_sub(b, a);
734 }
735 else {
736 if (b->ob_size < 0)
737 z = x_sub(a, b);
738 else
739 z = x_add(a, b);
740 }
741 return (object *)z;
742}
743
744static object *
745long_sub(a, w)
746 longobject *a;
747 object *w;
748{
749 longobject *b;
750 longobject *z;
751
752 if (!is_longobject(w)) {
753 err_badarg();
754 return NULL;
755 }
756 b = (longobject *)w;
757
758 if (a->ob_size < 0) {
759 if (b->ob_size < 0)
760 z = x_sub(a, b);
761 else
762 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000763 if (z != NULL && z->ob_size != 0)
764 z->ob_size = ~z->ob_size;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000765 }
766 else {
767 if (b->ob_size < 0)
768 z = x_add(a, b);
769 else
770 z = x_sub(a, b);
771 }
772 return (object *)z;
773}
774
775static object *
776long_mul(a, w)
777 longobject *a;
778 object *w;
779{
780 longobject *b;
781 int size_a;
782 int size_b;
783 longobject *z;
784 int i;
785
786 if (!is_longobject(w)) {
787 err_badarg();
788 return NULL;
789 }
790 b = (longobject *)w;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000791 size_a = ZABS(a->ob_size);
792 size_b = ZABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000793 z = alloclongobject(size_a + size_b);
794 if (z == NULL)
795 return NULL;
796 for (i = 0; i < z->ob_size; ++i)
797 z->ob_digit[i] = 0;
798 for (i = 0; i < size_a; ++i) {
799 twodigits carry = 0;
800 twodigits f = a->ob_digit[i];
801 int j;
802
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000803 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000804 DECREF(z);
805 err_set(KeyboardInterrupt);
806 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000807 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000808 for (j = 0; j < size_b; ++j) {
809 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
810 z->ob_digit[i+j] = carry & MASK;
811 carry >>= SHIFT;
812 }
813 for (; carry != 0; ++j) {
814 assert(i+j < z->ob_size);
815 carry += z->ob_digit[i+j];
816 z->ob_digit[i+j] = carry & MASK;
817 carry >>= SHIFT;
818 }
819 }
820 if (a->ob_size < 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000821 z->ob_size = ~z->ob_size;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000822 if (b->ob_size < 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000823 z->ob_size = ~z->ob_size;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000824 return (object *) long_normalize(z);
825}
826
827static object *
828long_div(v, w)
829 longobject *v;
830 register object *w;
831{
832 if (!is_longobject(w)) {
833 err_badarg();
834 return NULL;
835 }
836 return (object *) long_divrem(v, (longobject *)w, (longobject **)0);
837}
838
839static object *
840long_rem(v, w)
841 longobject *v;
842 register object *w;
843{
844 longobject *div, *rem = NULL;
845 if (!is_longobject(w)) {
846 err_badarg();
847 return NULL;
848 }
849 div = long_divrem(v, (longobject *)w, &rem);
850 if (div == NULL) {
851 XDECREF(rem);
852 rem = NULL;
853 }
854 else {
855 DECREF(div);
856 }
857 return (object *) rem;
858}
859
860/* The expression a mod b has the value a - b*floor(a/b).
861 The divrem function gives the remainder after division of
862 |a| by |b|, with the sign of a. This is also expressed
863 as a - b*trunc(a/b), if trunc truncates towards zero.
864 Some examples:
865 a b a rem b a mod b
866 13 10 3 3
867 -13 10 -3 7
868 13 -10 3 -7
869 -13 -10 -3 -3
870 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000871 have different signs. We then subtract one from the 'div'
872 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000873
874static object *
875long_divmod(v, w)
876 longobject *v;
877 register object *w;
878{
879 object *z;
880 longobject *div, *rem;
881 if (!is_longobject(w)) {
882 err_badarg();
883 return NULL;
884 }
885 div = long_divrem(v, (longobject *)w, &rem);
886 if (div == NULL) {
887 XDECREF(rem);
888 return NULL;
889 }
890 if ((v->ob_size < 0) != (((longobject *)w)->ob_size < 0)) {
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000891 longobject *temp;
892 longobject *one;
893 temp = (longobject *) long_add(rem, w);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000894 DECREF(rem);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000895 rem = temp;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000896 if (rem == NULL) {
897 DECREF(div);
898 return NULL;
899 }
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000900 one = (longobject *) newlongobject(1L);
901 if (one == NULL ||
902 (temp = (longobject *) long_sub(div, one)) == NULL) {
903 DECREF(rem);
904 DECREF(div);
905 return NULL;
906 }
907 DECREF(div);
908 div = temp;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000909 }
910 z = newtupleobject(2);
911 if (z != NULL) {
912 settupleitem(z, 0, (object *) div);
913 settupleitem(z, 1, (object *) rem);
914 }
915 else {
916 DECREF(div);
917 DECREF(rem);
918 }
919 return z;
920}
921
922static object *
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000923long_pow(a, w)
924 longobject *a;
925 object *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000926{
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000927 register longobject *b;
928 longobject *z;
929 int size_b, i;
930
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000931 if (!is_longobject(w)) {
932 err_badarg();
933 return NULL;
934 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000935
936 b = (longobject *)w;
937 size_b = b->ob_size;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000938 if (size_b == ~0)
939 size_b = 0;
940 else if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000941 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000942 return NULL;
943 }
944
945 z = (longobject *)newlongobject(1L);
946
947 INCREF(a);
948 for (i = 0; i < size_b; ++i) {
949 digit bi = b->ob_digit[i];
950 int j;
951
952 for (j = 0; j < SHIFT; ++j) {
953 longobject *temp;
954
955 if (bi & 1) {
956 temp = (longobject *)long_mul(z, (object *)a);
957 DECREF(z);
958 z = temp;
959 if (z == NULL)
960 break;
961 }
962 bi >>= 1;
963 if (bi == 0 && i+1 == size_b)
964 break;
965 temp = (longobject *)long_mul(a, (object *)a);
966 DECREF(a);
967 a = temp;
968 if (a == NULL) {
969 DECREF(z);
970 z = NULL;
971 break;
972 }
973 }
974 if (a == NULL)
975 break;
976 }
977 XDECREF(a);
978 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000979}
980
981static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +0000982long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000983 longobject *v;
984{
985 longobject *z;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000986 int i = ZABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000987 z = alloclongobject(i);
988 if (z != NULL) {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000989 z->ob_size = ~ v->ob_size;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000990 while (--i >= 0)
991 z->ob_digit[i] = v->ob_digit[i];
992 }
993 return (object *)z;
994}
995
996static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +0000997long_pos(v)
998 longobject *v;
999{
1000 if (v->ob_size == ~0)
1001 return long_invert(v);
1002 else {
1003 INCREF(v);
1004 return (object *)v;
1005 }
1006}
1007
1008static object *
1009long_neg(v)
1010 longobject *v;
1011{
1012 if (v->ob_size != 0)
1013 return long_invert(v);
1014 else {
1015 INCREF(v);
1016 return (object *)v;
1017 }
1018}
1019
1020static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001021long_abs(v)
1022 longobject *v;
1023{
1024 if (v->ob_size < 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001025 return long_invert(v);
1026 else {
1027 INCREF(v);
1028 return (object *)v;
1029 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001030}
1031
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001032static int
1033long_nonzero(v)
1034 longobject *v;
1035{
Guido van Rossumc6913e71991-11-19 20:26:46 +00001036 return ZABS(v->ob_size) != 0;
1037}
1038
1039static object *
1040long_rshift(a, b)
1041 longobject *a;
1042 object *b;
1043{
1044 longobject *z;
1045 long shiftby;
1046 int newsize, wordshift, loshift, hishift, i, j;
1047 digit lomask, himask;
1048
1049 if (!is_longobject(b)) {
1050 err_badarg();
1051 return NULL;
1052 }
1053 shiftby = getlongvalue(b);
1054 if (shiftby == -1L && err_occurred())
1055 return NULL;
1056 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001057 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001058 return NULL;
1059 }
1060 if (shiftby > MASK) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001061 err_setstr(ValueError, "outrageous shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001062 return NULL;
1063 }
1064 wordshift = shiftby / SHIFT;
1065 newsize = ZABS(a->ob_size) - wordshift;
1066 if (newsize <= 0) {
1067 z = alloclongobject(0);
1068 if (a->ob_size < 0 && z != NULL)
1069 z->ob_size = ~0;
1070 return (object *)z;
1071 }
1072 loshift = shiftby % SHIFT;
1073 hishift = SHIFT - loshift;
1074 lomask = ((digit)1 << hishift) - 1;
1075 himask = MASK ^ lomask;
1076 z = alloclongobject(newsize);
1077 if (z == NULL)
1078 return NULL;
1079 if (a->ob_size < 0)
1080 z->ob_size = ~z->ob_size;
1081 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1082 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1083 if (i+1 < newsize)
1084 z->ob_digit[i] |=
1085 (a->ob_digit[j+1] << hishift) & himask;
1086 }
1087 return (object *) long_znormalize(z);
1088}
1089
1090static object *
1091long_lshift(a, b)
1092 longobject *a;
1093 object *b;
1094{
1095 longobject *z;
1096 long shiftby;
1097 int newsize, wordshift, loshift, hishift, i, j;
1098 digit lomask, himask;
1099
1100 if (!is_longobject(b)) {
1101 err_badarg();
1102 return NULL;
1103 }
1104 shiftby = getlongvalue(b);
1105 if (shiftby == -1L && err_occurred())
1106 return NULL;
1107 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001108 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001109 return NULL;
1110 }
1111 if (shiftby > MASK) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001112 err_setstr(ValueError, "outrageous shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001113 return NULL;
1114 }
1115 if (shiftby % SHIFT == 0) {
1116 wordshift = shiftby / SHIFT;
1117 loshift = 0;
1118 hishift = SHIFT;
1119 newsize = ZABS(a->ob_size) + wordshift;
1120 lomask = MASK;
1121 himask = 0;
1122 }
1123 else {
1124 wordshift = shiftby / SHIFT + 1;
1125 loshift = SHIFT - shiftby%SHIFT;
1126 hishift = shiftby % SHIFT;
1127 newsize = ZABS(a->ob_size) + wordshift;
1128 lomask = ((digit)1 << hishift) - 1;
1129 himask = MASK ^ lomask;
1130 }
1131 z = alloclongobject(newsize);
1132 if (z == NULL)
1133 return NULL;
1134 if (a->ob_size < 0)
1135 z->ob_size = ~z->ob_size;
1136 for (i = 0; i < wordshift; i++)
1137 z->ob_digit[i] = 0;
1138 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1139 if (i > 0)
1140 z->ob_digit[i-1] |=
1141 (a->ob_digit[j] << hishift) & himask;
1142 z->ob_digit[i] =
1143 (a->ob_digit[j] >> loshift) & lomask;
1144 }
1145 return (object *) long_znormalize(z);
1146}
1147
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001148#define MAX(x, y) ((x) < (y) ? (y) : (x))
1149#define MIN(x, y) ((x) > (y) ? (y) : (x))
1150
Guido van Rossumc6913e71991-11-19 20:26:46 +00001151/* Logical or the absolute values of two long integers.
1152 The second value is first xor'ed with 'mask'. */
1153
1154static longobject *x_or PROTO((longobject *, longobject *, int));
1155static longobject *
1156x_or(a, b, mask)
1157 longobject *a, *b;
1158 int mask;
1159{
1160 int size_a = ZABS(a->ob_size), size_b = ZABS(b->ob_size);
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001161 int size_max = MAX(size_a, size_b);
1162 int size_min = MIN(size_a, size_b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001163 longobject *z;
1164 int i;
1165
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001166 z = alloclongobject(size_max);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001167 if (z == NULL)
1168 return NULL;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001169 for (i = 0; i < size_min; ++i) {
Guido van Rossumc6913e71991-11-19 20:26:46 +00001170 z->ob_digit[i] = a->ob_digit[i] | (b->ob_digit[i] ^ mask);
1171 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001172 /* At most one of the following two loops executes */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001173 for (; i < size_a; ++i) {
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001174 z->ob_digit[i] = a->ob_digit[i] | (0 ^ mask);
1175 }
1176 for (; i < size_b; ++i) {
1177 z->ob_digit[i] = 0 | (b->ob_digit[i] ^ mask);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001178 }
1179 return long_znormalize(z);
1180}
1181
1182/* Logical and the absolute values of two long integers.
1183 The second value is first xor'ed with 'mask'. */
1184
1185static longobject *x_and PROTO((longobject *, longobject *, int));
1186static longobject *
1187x_and(a, b, mask)
1188 longobject *a, *b;
1189 int mask;
1190{
1191 int size_a = ZABS(a->ob_size), size_b = ZABS(b->ob_size);
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001192 int size_max = MAX(size_a, size_b);
1193 int size_min = MIN(size_a, size_b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001194 longobject *z;
1195 int i;
1196
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001197 z = alloclongobject(size_max);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001198 if (z == NULL)
1199 return NULL;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001200 for (i = 0; i < size_min; ++i) {
Guido van Rossumc6913e71991-11-19 20:26:46 +00001201 z->ob_digit[i] = a->ob_digit[i] & (b->ob_digit[i] ^ mask);
1202 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001203 /* At most one of the following two loops executes */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001204 for (; i < size_a; ++i) {
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001205 z->ob_digit[i] = a->ob_digit[i] & (0 ^ mask);
1206 }
1207 for (; i < size_b; ++i) {
1208 z->ob_digit[i] = 0 & (b->ob_digit[i] ^ mask);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001209 }
1210 return long_znormalize(z);
1211}
1212
1213/* Logical xor the absolute values of two long integers.
1214 The second value is first xor'ed with 'mask'. */
1215
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001216static longobject *x_xor PROTO((longobject *, longobject *, int));
Guido van Rossumc6913e71991-11-19 20:26:46 +00001217static longobject *
1218x_xor(a, b, mask)
1219 longobject *a, *b;
1220 int mask;
1221{
1222 int size_a = ZABS(a->ob_size), size_b = ZABS(b->ob_size);
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001223 int size_max = MAX(size_a, size_b);
1224 int size_min = MIN(size_a, size_b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001225 longobject *z;
1226 int i;
1227
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001228 z = alloclongobject(size_max);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001229 if (z == NULL)
1230 return NULL;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001231 for (i = 0; i < size_min; ++i) {
Guido van Rossumc6913e71991-11-19 20:26:46 +00001232 z->ob_digit[i] = a->ob_digit[i] ^ (b->ob_digit[i] ^ mask);
1233 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001234 /* At most one of the following two loops executes */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001235 for (; i < size_a; ++i) {
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001236 z->ob_digit[i] = a->ob_digit[i] ^ (0 ^ mask);
1237 }
1238 for (; i < size_b; ++i) {
1239 z->ob_digit[i] = 0 ^ (b->ob_digit[i] ^ mask);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001240 }
1241 return long_znormalize(z);
1242}
1243
Guido van Rossumc6913e71991-11-19 20:26:46 +00001244static object *
1245long_and(a, w)
1246 longobject *a;
1247 object *w;
1248{
1249 longobject *b, *z;
1250
1251 if (!is_longobject(w)) {
1252 err_badarg();
1253 return NULL;
1254 }
1255 b = (longobject *)w;
1256
1257 if (a->ob_size >= 0 && b->ob_size >= 0)
1258 z = x_and(a, b, 0);
1259 else if (a->ob_size >= 0 && b->ob_size < 0)
1260 z = x_and(a, b, MASK);
1261 else if (a->ob_size < 0 && b->ob_size >= 0)
1262 z = x_and(b, a, MASK);
1263 else {
1264 z = x_or(a, b, 0);
1265 z->ob_size = ~z->ob_size;
1266 }
1267 return (object *)z;
1268}
1269
1270static object *
1271long_xor(a, w)
1272 longobject *a;
1273 object *w;
1274{
1275 longobject *b, *z;
1276
1277 if (!is_longobject(w)) {
1278 err_badarg();
1279 return NULL;
1280 }
1281 b = (longobject *)w;
1282
1283 if (a->ob_size >= 0 && b->ob_size >= 0)
1284 z = x_xor(a, b, 0);
1285 else if (a->ob_size >= 0 && b->ob_size < 0)
1286 z = x_xor(a, b, MASK);
1287 else if (a->ob_size < 0 && b->ob_size >= 0)
1288 z = x_xor(b, a, MASK);
1289 else {
1290 z = x_xor(a, b, 0);
1291 z->ob_size = ~z->ob_size;
1292 }
1293 return (object *)z;
1294}
1295
1296static object *
1297long_or(a, w)
1298 longobject *a;
1299 object *w;
1300{
1301 longobject *b, *z;
1302
1303 if (!is_longobject(w)) {
1304 err_badarg();
1305 return NULL;
1306 }
1307 b = (longobject *)w;
1308
1309 if (a->ob_size >= 0 && b->ob_size >= 0)
1310 z = x_or(a, b, 0);
1311 else {
1312 if (a->ob_size < 0 && b->ob_size >= 0)
1313 z = x_and(a, b, MASK);
1314 else if (a->ob_size >= 0 && b->ob_size < 0)
1315 z = x_and(b, a, MASK);
1316 else
1317 z = x_and(a, b, 0);
1318 z->ob_size = ~z->ob_size;
1319 }
1320 return (object *)z;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001321}
1322
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001323static number_methods long_as_number = {
1324 long_add, /*nb_add*/
1325 long_sub, /*nb_subtract*/
1326 long_mul, /*nb_multiply*/
1327 long_div, /*nb_divide*/
1328 long_rem, /*nb_remainder*/
1329 long_divmod, /*nb_divmod*/
1330 long_pow, /*nb_power*/
1331 long_neg, /*nb_negative*/
1332 long_pos, /*tp_positive*/
1333 long_abs, /*tp_absolute*/
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001334 long_nonzero, /*tp_nonzero*/
Guido van Rossumc6913e71991-11-19 20:26:46 +00001335 long_invert, /*nb_invert*/
1336 long_lshift, /*nb_lshift*/
1337 long_rshift, /*nb_rshift*/
1338 long_and, /*nb_and*/
1339 long_xor, /*nb_xor*/
1340 long_or, /*nb_or*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001341};
1342
1343typeobject Longtype = {
1344 OB_HEAD_INIT(&Typetype)
1345 0,
1346 "long int",
1347 sizeof(longobject) - sizeof(digit),
1348 sizeof(digit),
1349 long_dealloc, /*tp_dealloc*/
1350 long_print, /*tp_print*/
1351 0, /*tp_getattr*/
1352 0, /*tp_setattr*/
1353 long_compare, /*tp_compare*/
1354 long_repr, /*tp_repr*/
1355 &long_as_number,/*tp_as_number*/
1356 0, /*tp_as_sequence*/
1357 0, /*tp_as_mapping*/
1358};