blob: de7ff3985e26f9ccc65314fb0c2b661f626b7762 [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 Rossum149e9ea1991-06-03 10:58:24 +000034/* Forward: */
35extern object *long_mul PROTO((longobject *, object *));
36extern object *long_add PROTO((longobject *, object *));
37extern object *long_neg PROTO((longobject *));
38
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000039static int ticker; /* XXX Could be shared with ceval? */
40
41#define INTRCHECK(block) \
42 if (--ticker < 0) { \
43 ticker = 100; \
44 if (intrcheck()) { block; } \
45 }
46
Guido van Rossumedcc38a1991-05-05 20:09:44 +000047/* Normalize (remove leading zeros from) a long int object.
48 Doesn't attempt to free the storage--in most cases, due to the nature
49 of the algorithms used, this could save at most be one word anyway. */
50
51longobject *
52long_normalize(v)
53 register longobject *v;
54{
55 int j = ABS(v->ob_size);
56 register int i = j;
57
58 while (i > 0 && v->ob_digit[i-1] == 0)
59 --i;
60 if (i != j)
61 v->ob_size = (v->ob_size < 0) ? -i : i;
62 return v;
63}
64
65/* Allocate a new long int object with size digits.
66 Return NULL and set exception if we run out of memory. */
67
68longobject *
69alloclongobject(size)
70 int size;
71{
72 return NEWVAROBJ(longobject, &Longtype, size);
73}
74
75/* Create a new long int object from a C long int */
76
77object *
78newlongobject(ival)
79 long ival;
80{
81 /* Assume a C long fits in at most 3 'digits' */
82 longobject *v = alloclongobject(3);
83 if (v != NULL) {
84 if (ival < 0) {
85 ival = -ival;
86 v->ob_size = -v->ob_size;
87 }
88 v->ob_digit[0] = ival & MASK;
89 v->ob_digit[1] = (ival >> SHIFT) & MASK;
90 v->ob_digit[2] = (ival >> (2*SHIFT)) & MASK;
91 v = long_normalize(v);
92 }
93 return (object *)v;
94}
95
Guido van Rossum149e9ea1991-06-03 10:58:24 +000096/* Create a new long int object from a C double */
97
98object *
99dnewlongobject(dval)
100 double dval;
101{
102 longobject *v;
103 double frac;
104 int i, ndig, expo, neg;
105 neg = 0;
106 if (dval < 0.0) {
107 neg = 1;
108 dval = -dval;
109 }
110 frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
111 if (expo <= 0)
112 return newlongobject(0L);
113 ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
114 v = alloclongobject(ndig);
115 if (v == NULL)
116 return NULL;
117 frac = ldexp(frac, (expo-1) % SHIFT + 1);
118 for (i = ndig; --i >= 0; ) {
119 long bits = (long)frac;
120 v->ob_digit[i] = bits;
121 frac = frac - (double)bits;
122 frac = ldexp(frac, SHIFT);
123 }
124 if (neg)
125 v->ob_size = -v->ob_size;
126 return (object *)v;
127}
128
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000129/* Get a C long int from a long int object.
130 Returns -1 and sets an error condition if overflow occurs. */
131
132long
133getlongvalue(vv)
134 object *vv;
135{
136 register longobject *v;
137 long x, prev;
138 int i, sign;
139
140 if (vv == NULL || !is_longobject(vv)) {
141 err_badcall();
142 return -1;
143 }
144 v = (longobject *)vv;
145 i = v->ob_size;
146 sign = 1;
147 x = 0;
148 if (i < 0) {
149 sign = -1;
150 i = -i;
151 }
152 while (--i >= 0) {
153 prev = x;
154 x = (x << SHIFT) + v->ob_digit[i];
155 if ((x >> SHIFT) != prev) {
156 err_setstr(RuntimeError,
157 "long int too long to convert");
158 return -1;
159 }
160 }
161 return x * sign;
162}
163
164/* Get a C double from a long int object. No overflow check. */
165
166double
167dgetlongvalue(vv)
168 object *vv;
169{
170 register longobject *v;
171 double x;
172 double multiplier = (double) (1L << SHIFT);
173 int i, sign;
174
175 if (vv == NULL || !is_longobject(vv)) {
176 err_badcall();
177 return -1;
178 }
179 v = (longobject *)vv;
180 i = v->ob_size;
181 sign = 1;
182 x = 0.0;
183 if (i < 0) {
184 sign = -1;
185 i = -i;
186 }
187 while (--i >= 0) {
188 x = x*multiplier + v->ob_digit[i];
189 }
190 return x * sign;
191}
192
193/* Multiply by a single digit, ignoring the sign. */
194
195longobject *
196mul1(a, n)
197 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000198 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000199{
200 return muladd1(a, n, (digit)0);
201}
202
203/* Multiply by a single digit and add a single digit, ignoring the sign. */
204
205longobject *
206muladd1(a, n, extra)
207 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000208 wdigit n;
209 wdigit extra;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000210{
211 int size_a = ABS(a->ob_size);
212 longobject *z = alloclongobject(size_a+1);
213 twodigits carry = extra;
214 int i;
215
216 if (z == NULL)
217 return NULL;
218 for (i = 0; i < size_a; ++i) {
219 carry += (twodigits)a->ob_digit[i] * n;
220 z->ob_digit[i] = carry & MASK;
221 carry >>= SHIFT;
222 }
223 z->ob_digit[i] = carry;
224 return long_normalize(z);
225}
226
227/* Divide a long integer by a digit, returning both the quotient
228 (as function result) and the remainder (through *prem).
229 The sign of a is ignored; n should not be zero. */
230
231longobject *
232divrem1(a, n, prem)
233 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000234 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000235 digit *prem;
236{
237 int size = ABS(a->ob_size);
238 longobject *z;
239 int i;
240 twodigits rem = 0;
241
242 assert(n > 0 && n <= MASK);
243 z = alloclongobject(size);
244 if (z == NULL)
245 return NULL;
246 for (i = size; --i >= 0; ) {
247 rem = (rem << SHIFT) + a->ob_digit[i];
248 z->ob_digit[i] = rem/n;
249 rem %= n;
250 }
251 *prem = rem;
252 return long_normalize(z);
253}
254
255/* Convert a long int object to a string, using a given conversion base.
256 Return a string object. */
257
258stringobject *
259long_format(a, base)
260 longobject *a;
261 int base;
262{
263 stringobject *str;
264 int i;
265 int size_a = ABS(a->ob_size);
266 char *p;
267 int bits;
268 char sign = '\0';
269
270 assert(base >= 2 && base <= 36);
271
272 /* Compute a rough upper bound for the length of the string */
273 i = base;
274 bits = 0;
275 while (i > 1) {
276 ++bits;
277 i >>= 1;
278 }
279 i = 1 + (size_a*SHIFT + bits-1) / bits;
280 str = (stringobject *) newsizedstringobject((char *)0, i);
281 if (str == NULL)
282 return NULL;
283 p = GETSTRINGVALUE(str) + i;
284 *p = '\0';
285 if (a->ob_size < 0)
286 sign = '-';
287
288 INCREF(a);
289 do {
290 digit rem;
291 longobject *temp = divrem1(a, (digit)base, &rem);
292 if (temp == NULL) {
293 DECREF(a);
294 DECREF(str);
295 return NULL;
296 }
297 if (rem < 10)
298 rem += '0';
299 else
300 rem += 'A'-10;
301 assert(p > GETSTRINGVALUE(str));
302 *--p = rem;
303 DECREF(a);
304 a = temp;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000305 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000306 DECREF(a);
307 DECREF(str);
308 err_set(KeyboardInterrupt);
309 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000310 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000311 } while (a->ob_size != 0);
312 DECREF(a);
313 if (sign)
314 *--p = sign;
315 if (p != GETSTRINGVALUE(str)) {
316 char *q = GETSTRINGVALUE(str);
317 assert(p > q);
318 do {
319 } while ((*q++ = *p++) != '\0');
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000320 q--;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000321 resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
322 }
323 return str;
324}
325
326/* Convert a string to a long int object, in a given base.
327 Base zero implies a default depending on the number. */
328
329object *
330long_scan(str, base)
331 char *str;
332 int base;
333{
334 int sign = 1;
335 longobject *z;
336
337 assert(base == 0 || base >= 2 && base <= 36);
338 if (*str == '+')
339 ++str;
340 else if (*str == '-') {
341 ++str;
342 sign = -1;
343 }
344 if (base == 0) {
345 if (str[0] != '0')
346 base = 10;
347 else if (str[1] == 'x' || str[1] == 'X')
348 base = 16;
349 else
350 base = 8;
351 }
352 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
353 str += 2;
354 z = alloclongobject(0);
355 for ( ; z != NULL; ++str) {
356 int k = -1;
357 longobject *temp;
358
359 if (*str <= '9')
360 k = *str - '0';
361 else if (*str >= 'a')
362 k = *str - 'a' + 10;
363 else if (*str >= 'A')
364 k = *str - 'A' + 10;
365 if (k < 0 || k >= base)
366 break;
367 temp = muladd1(z, (digit)base, (digit)k);
368 DECREF(z);
369 z = temp;
370 }
371 if (z != NULL)
372 z->ob_size *= sign;
373 return (object *) z;
374}
375
376static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
377
378/* Long division with remainder, top-level routine */
379
380longobject *
381long_divrem(a, b, prem)
382 longobject *a, *b;
383 longobject **prem;
384{
385 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
386 longobject *z;
387
388 if (size_b == 0) {
389 if (prem != NULL)
390 *prem = NULL;
391 err_setstr(RuntimeError, "long division by zero");
392 return NULL;
393 }
394 if (size_a < size_b ||
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000395 size_a == size_b &&
396 a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000397 /* |a| < |b|. */
398 if (prem != NULL) {
399 INCREF(a);
400 *prem = a;
401 }
402 return alloclongobject(0);
403 }
404 if (size_b == 1) {
405 digit rem = 0;
406 z = divrem1(a, b->ob_digit[0], &rem);
407 if (prem != NULL) {
408 if (z == NULL)
409 *prem = NULL;
410 else
411 *prem = (longobject *)
412 newlongobject((long)rem);
413 }
414 }
415 else
416 z = x_divrem(a, b, prem);
417 /* Set the signs.
418 The quotient z has the sign of a*b;
419 the remainder r has the sign of a,
420 so a = b*z + r. */
421 if (z != NULL) {
422 if ((a->ob_size < 0) != (b->ob_size < 0))
423 z->ob_size = - z->ob_size;
424 if (prem != NULL && *prem != NULL && a->ob_size < 0)
425 (*prem)->ob_size = - (*prem)->ob_size;
426 }
427 return z;
428}
429
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000430/* Unsigned long division with remainder -- the algorithm */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000431
432static longobject *
433x_divrem(v1, w1, prem)
434 longobject *v1, *w1;
435 longobject **prem;
436{
437 int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
438 digit d = (twodigits)BASE / (w1->ob_digit[size_w-1] + 1);
439 longobject *v = mul1(v1, d);
440 longobject *w = mul1(w1, d);
441 longobject *a;
442 int j, k;
443
444 if (v == NULL || w == NULL) {
445 XDECREF(v);
446 XDECREF(w);
447 if (prem != NULL)
448 *prem = NULL;
449 return NULL;
450 }
451
452 assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000453 assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000454 assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
455
456 size_v = ABS(v->ob_size);
457 a = alloclongobject(size_v - size_w + 1);
458
459 for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
460 digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
461 twodigits q;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000462 stwodigits carry = 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000463 int i;
464
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000465 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000466 DECREF(a);
467 a = NULL;
468 err_set(KeyboardInterrupt);
469 break;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000470 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000471 if (vj == w->ob_digit[size_w-1])
472 q = MASK;
473 else
474 q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
475 w->ob_digit[size_w-1];
476
477 while (w->ob_digit[size_w-2]*q >
478 ((
479 ((twodigits)vj << SHIFT)
480 + v->ob_digit[j-1]
481 - q*w->ob_digit[size_w-1]
482 ) << SHIFT)
483 + v->ob_digit[j-2])
484 --q;
485
486 for (i = 0; i < size_w && i+k < size_v; ++i) {
487 twodigits z = w->ob_digit[i] * q;
488 digit zz = z >> SHIFT;
489 carry += v->ob_digit[i+k] - z + ((twodigits)zz << SHIFT);
490 v->ob_digit[i+k] = carry & MASK;
491 carry = (carry >> SHIFT) - zz;
492 }
493
494 if (i+k < size_v) {
495 carry += v->ob_digit[i+k];
496 v->ob_digit[i+k] = 0;
497 }
498
499 if (carry == 0)
500 a->ob_digit[k] = q;
501 else {
502 assert(carry == -1);
503 a->ob_digit[k] = q-1;
504 carry = 0;
505 for (i = 0; i < size_w && i+k < size_v; ++i) {
506 carry += v->ob_digit[i+k] + w->ob_digit[i];
507 v->ob_digit[i+k] = carry & MASK;
508 carry >>= SHIFT;
509 }
510 }
511 } /* for j, k */
512
513 if (a != NULL)
514 a = long_normalize(a);
515 if (prem != 0) {
516 if (a == NULL)
517 *prem = NULL;
518 else
519 *prem = divrem1(v, d, &d);
520 /* Using d as a dummy to receive the - unused - remainder */
521 }
522 DECREF(v);
523 DECREF(w);
524 return a;
525}
526
527/* Methods */
528
529static void
530long_dealloc(v)
531 longobject *v;
532{
533 DEL(v);
534}
535
536static void
537long_print(v, fp, flags)
538 longobject *v;
539 FILE *fp;
540 int flags;
541{
542 stringobject *str = long_format(v, 10);
543 if (str == NULL) {
544 err_clear();
545 fprintf(fp, "[err]");
546 }
547 else {
548 fprintf(fp, "%sL", GETSTRINGVALUE(str));
549 DECREF(str);
550 }
551}
552
553static object *
554long_repr(v)
555 longobject *v;
556{
557 stringobject *str = long_format(v, 10);
558 if (str != NULL) {
559 int len = getstringsize((object *)str);
560 resizestring((object **)&str, len + 1);
561 if (str != NULL)
562 GETSTRINGVALUE(str)[len] = 'L';
563 }
564 return (object *)str;
565}
566
567static int
568long_compare(a, b)
569 longobject *a, *b;
570{
571 int sign;
572
573 if (a->ob_size != b->ob_size)
574 sign = a->ob_size - b->ob_size;
575 else {
576 int i = ABS(a->ob_size);
577 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
578 ;
579 if (i < 0)
580 sign = 0;
581 else
582 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
583 }
584 return sign;
585}
586
587/* Add the absolute values of two long integers. */
588
589static longobject *x_add PROTO((longobject *, longobject *));
590static longobject *
591x_add(a, b)
592 longobject *a, *b;
593{
594 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
595 longobject *z;
596 int i;
597 digit carry = 0;
598
599 /* Ensure a is the larger of the two: */
600 if (size_a < size_b) {
601 { longobject *temp = a; a = b; b = temp; }
602 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
603 }
604 z = alloclongobject(size_a+1);
605 if (z == NULL)
606 return NULL;
607 for (i = 0; i < size_b; ++i) {
608 carry += a->ob_digit[i] + b->ob_digit[i];
609 z->ob_digit[i] = carry & MASK;
610 /* The following assumes unsigned shifts don't
611 propagate the sign bit. */
612 carry >>= SHIFT;
613 }
614 for (; i < size_a; ++i) {
615 carry += a->ob_digit[i];
616 z->ob_digit[i] = carry & MASK;
617 carry >>= SHIFT;
618 }
619 z->ob_digit[i] = carry;
620 return long_normalize(z);
621}
622
623/* Subtract the absolute values of two integers. */
624
625static longobject *x_sub PROTO((longobject *, longobject *));
626static longobject *
627x_sub(a, b)
628 longobject *a, *b;
629{
630 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
631 longobject *z;
632 int i;
633 int sign = 1;
634 digit borrow = 0;
635
636 /* Ensure a is the larger of the two: */
637 if (size_a < size_b) {
638 sign = -1;
639 { longobject *temp = a; a = b; b = temp; }
640 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
641 }
642 else if (size_a == size_b) {
643 /* Find highest digit where a and b differ: */
644 i = size_a;
645 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
646 ;
647 if (i < 0)
648 return alloclongobject(0);
649 if (a->ob_digit[i] < b->ob_digit[i]) {
650 sign = -1;
651 { longobject *temp = a; a = b; b = temp; }
652 }
653 size_a = size_b = i+1;
654 }
655 z = alloclongobject(size_a);
656 if (z == NULL)
657 return NULL;
658 for (i = 0; i < size_b; ++i) {
659 /* The following assumes unsigned arithmetic
660 works module 2**N for some N>SHIFT. */
661 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
662 z->ob_digit[i] = borrow & MASK;
663 borrow >>= SHIFT;
664 borrow &= 1; /* Keep only one sign bit */
665 }
666 for (; i < size_a; ++i) {
667 borrow = a->ob_digit[i] - borrow;
668 z->ob_digit[i] = borrow & MASK;
669 borrow >>= SHIFT;
670 }
671 assert(borrow == 0);
672 z->ob_size *= sign;
673 return long_normalize(z);
674}
675
676static object *
677long_add(a, w)
678 longobject *a;
679 object *w;
680{
681 longobject *b;
682 longobject *z;
683
684 if (!is_longobject(w)) {
685 err_badarg();
686 return NULL;
687 }
688 b = (longobject *)w;
689
690 if (a->ob_size < 0) {
691 if (b->ob_size < 0) {
692 z = x_add(a, b);
693 if (z != NULL)
694 z->ob_size = -z->ob_size;
695 }
696 else
697 z = x_sub(b, a);
698 }
699 else {
700 if (b->ob_size < 0)
701 z = x_sub(a, b);
702 else
703 z = x_add(a, b);
704 }
705 return (object *)z;
706}
707
708static object *
709long_sub(a, w)
710 longobject *a;
711 object *w;
712{
713 longobject *b;
714 longobject *z;
715
716 if (!is_longobject(w)) {
717 err_badarg();
718 return NULL;
719 }
720 b = (longobject *)w;
721
722 if (a->ob_size < 0) {
723 if (b->ob_size < 0)
724 z = x_sub(a, b);
725 else
726 z = x_add(a, b);
727 if (z != NULL)
728 z->ob_size = -z->ob_size;
729 }
730 else {
731 if (b->ob_size < 0)
732 z = x_add(a, b);
733 else
734 z = x_sub(a, b);
735 }
736 return (object *)z;
737}
738
739static object *
740long_mul(a, w)
741 longobject *a;
742 object *w;
743{
744 longobject *b;
745 int size_a;
746 int size_b;
747 longobject *z;
748 int i;
749
750 if (!is_longobject(w)) {
751 err_badarg();
752 return NULL;
753 }
754 b = (longobject *)w;
755 size_a = ABS(a->ob_size);
756 size_b = ABS(b->ob_size);
757 z = alloclongobject(size_a + size_b);
758 if (z == NULL)
759 return NULL;
760 for (i = 0; i < z->ob_size; ++i)
761 z->ob_digit[i] = 0;
762 for (i = 0; i < size_a; ++i) {
763 twodigits carry = 0;
764 twodigits f = a->ob_digit[i];
765 int j;
766
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000767 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000768 DECREF(z);
769 err_set(KeyboardInterrupt);
770 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000771 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000772 for (j = 0; j < size_b; ++j) {
773 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
774 z->ob_digit[i+j] = carry & MASK;
775 carry >>= SHIFT;
776 }
777 for (; carry != 0; ++j) {
778 assert(i+j < z->ob_size);
779 carry += z->ob_digit[i+j];
780 z->ob_digit[i+j] = carry & MASK;
781 carry >>= SHIFT;
782 }
783 }
784 if (a->ob_size < 0)
785 z->ob_size = -z->ob_size;
786 if (b->ob_size < 0)
787 z->ob_size = -z->ob_size;
788 return (object *) long_normalize(z);
789}
790
791static object *
792long_div(v, w)
793 longobject *v;
794 register object *w;
795{
796 if (!is_longobject(w)) {
797 err_badarg();
798 return NULL;
799 }
800 return (object *) long_divrem(v, (longobject *)w, (longobject **)0);
801}
802
803static object *
804long_rem(v, w)
805 longobject *v;
806 register object *w;
807{
808 longobject *div, *rem = NULL;
809 if (!is_longobject(w)) {
810 err_badarg();
811 return NULL;
812 }
813 div = long_divrem(v, (longobject *)w, &rem);
814 if (div == NULL) {
815 XDECREF(rem);
816 rem = NULL;
817 }
818 else {
819 DECREF(div);
820 }
821 return (object *) rem;
822}
823
824/* The expression a mod b has the value a - b*floor(a/b).
825 The divrem function gives the remainder after division of
826 |a| by |b|, with the sign of a. This is also expressed
827 as a - b*trunc(a/b), if trunc truncates towards zero.
828 Some examples:
829 a b a rem b a mod b
830 13 10 3 3
831 -13 10 -3 7
832 13 -10 3 -7
833 -13 -10 -3 -3
834 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000835 have different signs. We then subtract one from the 'div'
836 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000837
838static object *
839long_divmod(v, w)
840 longobject *v;
841 register object *w;
842{
843 object *z;
844 longobject *div, *rem;
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 return NULL;
853 }
854 if ((v->ob_size < 0) != (((longobject *)w)->ob_size < 0)) {
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000855 longobject *temp;
856 longobject *one;
857 temp = (longobject *) long_add(rem, w);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000858 DECREF(rem);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000859 rem = temp;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000860 if (rem == NULL) {
861 DECREF(div);
862 return NULL;
863 }
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000864 one = (longobject *) newlongobject(1L);
865 if (one == NULL ||
866 (temp = (longobject *) long_sub(div, one)) == NULL) {
867 DECREF(rem);
868 DECREF(div);
869 return NULL;
870 }
871 DECREF(div);
872 div = temp;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000873 }
874 z = newtupleobject(2);
875 if (z != NULL) {
876 settupleitem(z, 0, (object *) div);
877 settupleitem(z, 1, (object *) rem);
878 }
879 else {
880 DECREF(div);
881 DECREF(rem);
882 }
883 return z;
884}
885
886static object *
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000887long_pow(a, w)
888 longobject *a;
889 object *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000890{
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000891 register longobject *b;
892 longobject *z;
893 int size_b, i;
894
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000895 if (!is_longobject(w)) {
896 err_badarg();
897 return NULL;
898 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000899
900 b = (longobject *)w;
901 size_b = b->ob_size;
902 if (size_b < 0) {
903 err_setstr(RuntimeError, "long integer to the negative power");
904 return NULL;
905 }
906
907 z = (longobject *)newlongobject(1L);
908
909 INCREF(a);
910 for (i = 0; i < size_b; ++i) {
911 digit bi = b->ob_digit[i];
912 int j;
913
914 for (j = 0; j < SHIFT; ++j) {
915 longobject *temp;
916
917 if (bi & 1) {
918 temp = (longobject *)long_mul(z, (object *)a);
919 DECREF(z);
920 z = temp;
921 if (z == NULL)
922 break;
923 }
924 bi >>= 1;
925 if (bi == 0 && i+1 == size_b)
926 break;
927 temp = (longobject *)long_mul(a, (object *)a);
928 DECREF(a);
929 a = temp;
930 if (a == NULL) {
931 DECREF(z);
932 z = NULL;
933 break;
934 }
935 }
936 if (a == NULL)
937 break;
938 }
939 XDECREF(a);
940 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000941}
942
943static object *
944long_pos(v)
945 longobject *v;
946{
947 INCREF(v);
948 return (object *)v;
949}
950
951static object *
952long_neg(v)
953 longobject *v;
954{
955 longobject *z;
956 int i = v->ob_size;
957 if (i == 0)
958 return long_pos(v);
959 i = ABS(i);
960 z = alloclongobject(i);
961 if (z != NULL) {
962 z->ob_size = - v->ob_size;
963 while (--i >= 0)
964 z->ob_digit[i] = v->ob_digit[i];
965 }
966 return (object *)z;
967}
968
969static object *
970long_abs(v)
971 longobject *v;
972{
973 if (v->ob_size < 0)
974 return long_neg(v);
975 else
976 return long_pos(v);
977}
978
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000979static int
980long_nonzero(v)
981 longobject *v;
982{
983 return v->ob_size != 0;
984}
985
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000986static number_methods long_as_number = {
987 long_add, /*nb_add*/
988 long_sub, /*nb_subtract*/
989 long_mul, /*nb_multiply*/
990 long_div, /*nb_divide*/
991 long_rem, /*nb_remainder*/
992 long_divmod, /*nb_divmod*/
993 long_pow, /*nb_power*/
994 long_neg, /*nb_negative*/
995 long_pos, /*tp_positive*/
996 long_abs, /*tp_absolute*/
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000997 long_nonzero, /*tp_nonzero*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000998};
999
1000typeobject Longtype = {
1001 OB_HEAD_INIT(&Typetype)
1002 0,
1003 "long int",
1004 sizeof(longobject) - sizeof(digit),
1005 sizeof(digit),
1006 long_dealloc, /*tp_dealloc*/
1007 long_print, /*tp_print*/
1008 0, /*tp_getattr*/
1009 0, /*tp_setattr*/
1010 long_compare, /*tp_compare*/
1011 long_repr, /*tp_repr*/
1012 &long_as_number,/*tp_as_number*/
1013 0, /*tp_as_sequence*/
1014 0, /*tp_as_mapping*/
1015};