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