blob: 84fc5525b5a2040a3d61d55d2b48ce03dd264666 [file] [log] [blame]
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001/***********************************************************
Guido van Rossumbab9d031992-04-05 14:26:55 +00002Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Guido van Rossumedcc38a1991-05-05 20:09:44 +00003Netherlands.
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"
Guido van Rossume32e0141992-01-19 16:31:05 +000030#include "intrcheck.h"
Guido van Rossumedcc38a1991-05-05 20:09:44 +000031#include "longintrepr.h"
Guido van Rossum149e9ea1991-06-03 10:58:24 +000032#include <math.h>
Guido van Rossumedcc38a1991-05-05 20:09:44 +000033#include <assert.h>
34
Guido van Rossume32e0141992-01-19 16:31:05 +000035#define ABS(x) ((x) < 0 ? -(x) : (x))
36
37/* Forward */
38static longobject *long_normalize PROTO((longobject *));
39static longobject *mul1 PROTO((longobject *, wdigit));
40static longobject *muladd1 PROTO((longobject *, wdigit, wdigit));
41static longobject *divrem1 PROTO((longobject *, wdigit, digit *));
42
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000043static int ticker; /* XXX Could be shared with ceval? */
44
45#define INTRCHECK(block) \
46 if (--ticker < 0) { \
47 ticker = 100; \
48 if (intrcheck()) { block; } \
49 }
50
Guido van Rossumedcc38a1991-05-05 20:09:44 +000051/* Normalize (remove leading zeros from) a long int object.
52 Doesn't attempt to free the storage--in most cases, due to the nature
53 of the algorithms used, this could save at most be one word anyway. */
54
Guido van Rossum4c260ff1992-01-14 18:36:43 +000055static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +000056long_normalize(v)
57 register longobject *v;
58{
Guido van Rossum4c260ff1992-01-14 18:36:43 +000059 int j = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +000060 register int i = j;
61
62 while (i > 0 && v->ob_digit[i-1] == 0)
63 --i;
64 if (i != j)
Guido van Rossum4c260ff1992-01-14 18:36:43 +000065 v->ob_size = (v->ob_size < 0) ? -(i) : i;
Guido van Rossumedcc38a1991-05-05 20:09:44 +000066 return v;
67}
68
69/* Allocate a new long int object with size digits.
70 Return NULL and set exception if we run out of memory. */
71
72longobject *
73alloclongobject(size)
74 int size;
75{
76 return NEWVAROBJ(longobject, &Longtype, size);
77}
78
79/* Create a new long int object from a C long int */
80
81object *
82newlongobject(ival)
83 long ival;
84{
85 /* Assume a C long fits in at most 3 'digits' */
86 longobject *v = alloclongobject(3);
87 if (v != NULL) {
88 if (ival < 0) {
89 ival = -ival;
Guido van Rossum4c260ff1992-01-14 18:36:43 +000090 v->ob_size = -(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +000091 }
92 v->ob_digit[0] = ival & MASK;
93 v->ob_digit[1] = (ival >> SHIFT) & MASK;
94 v->ob_digit[2] = (ival >> (2*SHIFT)) & MASK;
95 v = long_normalize(v);
96 }
97 return (object *)v;
98}
99
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000100/* Create a new long int object from a C double */
101
102object *
103dnewlongobject(dval)
104 double dval;
105{
106 longobject *v;
107 double frac;
108 int i, ndig, expo, neg;
109 neg = 0;
110 if (dval < 0.0) {
111 neg = 1;
112 dval = -dval;
113 }
114 frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
115 if (expo <= 0)
116 return newlongobject(0L);
117 ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
118 v = alloclongobject(ndig);
119 if (v == NULL)
120 return NULL;
121 frac = ldexp(frac, (expo-1) % SHIFT + 1);
122 for (i = ndig; --i >= 0; ) {
123 long bits = (long)frac;
124 v->ob_digit[i] = bits;
125 frac = frac - (double)bits;
126 frac = ldexp(frac, SHIFT);
127 }
128 if (neg)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000129 v->ob_size = -(v->ob_size);
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000130 return (object *)v;
131}
132
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000133/* Get a C long int from a long int object.
134 Returns -1 and sets an error condition if overflow occurs. */
135
136long
137getlongvalue(vv)
138 object *vv;
139{
140 register longobject *v;
141 long x, prev;
142 int i, sign;
143
144 if (vv == NULL || !is_longobject(vv)) {
145 err_badcall();
146 return -1;
147 }
148 v = (longobject *)vv;
149 i = v->ob_size;
150 sign = 1;
151 x = 0;
152 if (i < 0) {
153 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000154 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000155 }
156 while (--i >= 0) {
157 prev = x;
158 x = (x << SHIFT) + v->ob_digit[i];
159 if ((x >> SHIFT) != prev) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000160 err_setstr(ValueError,
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000161 "long int too long to convert");
162 return -1;
163 }
164 }
165 return x * sign;
166}
167
168/* Get a C double from a long int object. No overflow check. */
169
170double
171dgetlongvalue(vv)
172 object *vv;
173{
174 register longobject *v;
175 double x;
176 double multiplier = (double) (1L << SHIFT);
177 int i, sign;
178
179 if (vv == NULL || !is_longobject(vv)) {
180 err_badcall();
181 return -1;
182 }
183 v = (longobject *)vv;
184 i = v->ob_size;
185 sign = 1;
186 x = 0.0;
187 if (i < 0) {
188 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000189 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000190 }
191 while (--i >= 0) {
192 x = x*multiplier + v->ob_digit[i];
193 }
194 return x * sign;
195}
196
197/* Multiply by a single digit, ignoring the sign. */
198
Guido van Rossume32e0141992-01-19 16:31:05 +0000199static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000200mul1(a, n)
201 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000202 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000203{
204 return muladd1(a, n, (digit)0);
205}
206
207/* Multiply by a single digit and add a single digit, ignoring the sign. */
208
Guido van Rossume32e0141992-01-19 16:31:05 +0000209static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000210muladd1(a, n, extra)
211 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000212 wdigit n;
213 wdigit extra;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000214{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000215 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000216 longobject *z = alloclongobject(size_a+1);
217 twodigits carry = extra;
218 int i;
219
220 if (z == NULL)
221 return NULL;
222 for (i = 0; i < size_a; ++i) {
223 carry += (twodigits)a->ob_digit[i] * n;
224 z->ob_digit[i] = carry & MASK;
225 carry >>= SHIFT;
226 }
227 z->ob_digit[i] = carry;
228 return long_normalize(z);
229}
230
231/* Divide a long integer by a digit, returning both the quotient
232 (as function result) and the remainder (through *prem).
233 The sign of a is ignored; n should not be zero. */
234
Guido van Rossume32e0141992-01-19 16:31:05 +0000235static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000236divrem1(a, n, prem)
237 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000238 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000239 digit *prem;
240{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000241 int size = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000242 longobject *z;
243 int i;
244 twodigits rem = 0;
245
246 assert(n > 0 && n <= MASK);
247 z = alloclongobject(size);
248 if (z == NULL)
249 return NULL;
250 for (i = size; --i >= 0; ) {
251 rem = (rem << SHIFT) + a->ob_digit[i];
252 z->ob_digit[i] = rem/n;
253 rem %= n;
254 }
255 *prem = rem;
256 return long_normalize(z);
257}
258
259/* Convert a long int object to a string, using a given conversion base.
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000260 Return a string object.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000261 If base is 8 or 16, add the proper prefix '0' or '0x'.
262 External linkage: used in bltinmodule.c by hex() and oct(). */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000263
Guido van Rossume32e0141992-01-19 16:31:05 +0000264object *
265long_format(aa, base)
266 object *aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000267 int base;
268{
Guido van Rossume32e0141992-01-19 16:31:05 +0000269 register longobject *a = (longobject *)aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000270 stringobject *str;
271 int i;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000272 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000273 char *p;
274 int bits;
275 char sign = '\0';
Guido van Rossume32e0141992-01-19 16:31:05 +0000276
277 if (a == NULL || !is_longobject(a)) {
278 err_badcall();
279 return NULL;
280 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000281 assert(base >= 2 && base <= 36);
282
283 /* Compute a rough upper bound for the length of the string */
284 i = base;
285 bits = 0;
286 while (i > 1) {
287 ++bits;
288 i >>= 1;
289 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000290 i = 6 + (size_a*SHIFT + bits-1) / bits;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000291 str = (stringobject *) newsizedstringobject((char *)0, i);
292 if (str == NULL)
293 return NULL;
294 p = GETSTRINGVALUE(str) + i;
295 *p = '\0';
Guido van Rossumc6913e71991-11-19 20:26:46 +0000296 *--p = 'L';
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000297 if (a->ob_size < 0)
298 sign = '-';
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000299
300 INCREF(a);
301 do {
302 digit rem;
303 longobject *temp = divrem1(a, (digit)base, &rem);
304 if (temp == NULL) {
305 DECREF(a);
306 DECREF(str);
307 return NULL;
308 }
309 if (rem < 10)
310 rem += '0';
311 else
312 rem += 'A'-10;
313 assert(p > GETSTRINGVALUE(str));
314 *--p = rem;
315 DECREF(a);
316 a = temp;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000317 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000318 DECREF(a);
319 DECREF(str);
320 err_set(KeyboardInterrupt);
321 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000322 })
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000323 } while (ABS(a->ob_size) != 0);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000324 DECREF(a);
Guido van Rossum2c475421992-08-14 15:13:07 +0000325 if (base == 8) {
326 if (size_a != 0)
327 *--p = '0';
328 }
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000329 else if (base == 16) {
330 *--p = 'x';
331 *--p = '0';
332 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000333 else if (base != 10) {
334 *--p = '#';
335 *--p = '0' + base%10;
336 if (base > 10)
337 *--p = '0' + base/10;
338 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000339 if (sign)
340 *--p = sign;
341 if (p != GETSTRINGVALUE(str)) {
342 char *q = GETSTRINGVALUE(str);
343 assert(p > q);
344 do {
345 } while ((*q++ = *p++) != '\0');
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000346 q--;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000347 resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
348 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000349 return (object *)str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000350}
351
352/* Convert a string to a long int object, in a given base.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000353 Base zero implies a default depending on the number.
354 External linkage: used in compile.c for literals. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000355
356object *
357long_scan(str, base)
358 char *str;
359 int base;
360{
361 int sign = 1;
362 longobject *z;
363
364 assert(base == 0 || base >= 2 && base <= 36);
365 if (*str == '+')
366 ++str;
367 else if (*str == '-') {
368 ++str;
369 sign = -1;
370 }
371 if (base == 0) {
372 if (str[0] != '0')
373 base = 10;
374 else if (str[1] == 'x' || str[1] == 'X')
375 base = 16;
376 else
377 base = 8;
378 }
379 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
380 str += 2;
381 z = alloclongobject(0);
382 for ( ; z != NULL; ++str) {
383 int k = -1;
384 longobject *temp;
385
386 if (*str <= '9')
387 k = *str - '0';
388 else if (*str >= 'a')
389 k = *str - 'a' + 10;
390 else if (*str >= 'A')
391 k = *str - 'A' + 10;
392 if (k < 0 || k >= base)
393 break;
394 temp = muladd1(z, (digit)base, (digit)k);
395 DECREF(z);
396 z = temp;
397 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000398 if (sign < 0 && z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000399 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000400 return (object *) z;
401}
402
403static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
Guido van Rossumc6913e71991-11-19 20:26:46 +0000404static object *long_pos PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000405static long_divrem PROTO((longobject *, longobject *,
406 longobject **, longobject **));
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000407
408/* Long division with remainder, top-level routine */
409
Guido van Rossume32e0141992-01-19 16:31:05 +0000410static int
411long_divrem(a, b, pdiv, prem)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000412 longobject *a, *b;
Guido van Rossume32e0141992-01-19 16:31:05 +0000413 longobject **pdiv;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000414 longobject **prem;
415{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000416 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000417 longobject *z;
418
419 if (size_b == 0) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000420 err_setstr(ZeroDivisionError, "long division or modulo");
421 return -1;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000422 }
423 if (size_a < size_b ||
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000424 size_a == size_b &&
425 a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000426 /* |a| < |b|. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000427 *pdiv = alloclongobject(0);
428 INCREF(a);
429 *prem = (longobject *) a;
430 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000431 }
432 if (size_b == 1) {
433 digit rem = 0;
434 z = divrem1(a, b->ob_digit[0], &rem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000435 if (z == NULL)
436 return -1;
437 *prem = (longobject *) newlongobject((long)rem);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000438 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000439 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000440 z = x_divrem(a, b, prem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000441 if (z == NULL)
442 return -1;
443 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000444 /* Set the signs.
445 The quotient z has the sign of a*b;
446 the remainder r has the sign of a,
447 so a = b*z + r. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000448 if ((a->ob_size < 0) != (b->ob_size < 0))
449 z->ob_size = -(z->ob_size);
450 if (a->ob_size < 0 && (*prem)->ob_size != 0)
451 (*prem)->ob_size = -((*prem)->ob_size);
452 *pdiv = z;
453 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000454}
455
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000456/* Unsigned long division with remainder -- the algorithm */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000457
458static longobject *
459x_divrem(v1, w1, prem)
460 longobject *v1, *w1;
461 longobject **prem;
462{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000463 int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000464 digit d = (twodigits)BASE / (w1->ob_digit[size_w-1] + 1);
465 longobject *v = mul1(v1, d);
466 longobject *w = mul1(w1, d);
467 longobject *a;
468 int j, k;
469
470 if (v == NULL || w == NULL) {
471 XDECREF(v);
472 XDECREF(w);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000473 return NULL;
474 }
475
476 assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000477 assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000478 assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000479
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000480 size_v = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000481 a = alloclongobject(size_v - size_w + 1);
482
483 for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
484 digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
485 twodigits q;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000486 stwodigits carry = 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000487 int i;
488
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000489 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000490 DECREF(a);
491 a = NULL;
492 err_set(KeyboardInterrupt);
493 break;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000494 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000495 if (vj == w->ob_digit[size_w-1])
496 q = MASK;
497 else
498 q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
499 w->ob_digit[size_w-1];
500
501 while (w->ob_digit[size_w-2]*q >
502 ((
503 ((twodigits)vj << SHIFT)
504 + v->ob_digit[j-1]
505 - q*w->ob_digit[size_w-1]
506 ) << SHIFT)
507 + v->ob_digit[j-2])
508 --q;
509
510 for (i = 0; i < size_w && i+k < size_v; ++i) {
511 twodigits z = w->ob_digit[i] * q;
512 digit zz = z >> SHIFT;
513 carry += v->ob_digit[i+k] - z + ((twodigits)zz << SHIFT);
514 v->ob_digit[i+k] = carry & MASK;
515 carry = (carry >> SHIFT) - zz;
516 }
517
518 if (i+k < size_v) {
519 carry += v->ob_digit[i+k];
520 v->ob_digit[i+k] = 0;
521 }
522
523 if (carry == 0)
524 a->ob_digit[k] = q;
525 else {
526 assert(carry == -1);
527 a->ob_digit[k] = q-1;
528 carry = 0;
529 for (i = 0; i < size_w && i+k < size_v; ++i) {
530 carry += v->ob_digit[i+k] + w->ob_digit[i];
531 v->ob_digit[i+k] = carry & MASK;
532 carry >>= SHIFT;
533 }
534 }
535 } /* for j, k */
536
Guido van Rossume32e0141992-01-19 16:31:05 +0000537 if (a != NULL) {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000538 a = long_normalize(a);
Guido van Rossume32e0141992-01-19 16:31:05 +0000539 *prem = divrem1(v, d, &d);
540 /* d receives the (unused) remainder */
541 if (*prem == NULL) {
542 DECREF(a);
543 a = NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000544 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000545 }
546 DECREF(v);
547 DECREF(w);
548 return a;
549}
550
551/* Methods */
552
Guido van Rossume32e0141992-01-19 16:31:05 +0000553/* Forward */
Guido van Rossum8b27d921992-03-27 17:27:05 +0000554static void long_dealloc PROTO((object *));
555static int long_print PROTO((object *, FILE *, int));
556static object *long_repr PROTO((object *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000557static int long_compare PROTO((longobject *, longobject *));
558
559static object *long_add PROTO((longobject *, longobject *));
560static object *long_sub PROTO((longobject *, longobject *));
561static object *long_mul PROTO((longobject *, longobject *));
562static object *long_div PROTO((longobject *, longobject *));
563static object *long_mod PROTO((longobject *, longobject *));
564static object *long_divmod PROTO((longobject *, longobject *));
565static object *long_pow PROTO((longobject *, longobject *));
566static object *long_neg PROTO((longobject *));
567static object *long_pos PROTO((longobject *));
568static object *long_abs PROTO((longobject *));
569static int long_nonzero PROTO((longobject *));
570static object *long_invert PROTO((longobject *));
571static object *long_lshift PROTO((longobject *, longobject *));
572static object *long_rshift PROTO((longobject *, longobject *));
573static object *long_and PROTO((longobject *, longobject *));
574static object *long_xor PROTO((longobject *, longobject *));
575static object *long_or PROTO((longobject *, longobject *));
576
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000577static void
578long_dealloc(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000579 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000580{
581 DEL(v);
582}
583
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000584static object *
585long_repr(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000586 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000587{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000588 return long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000589}
590
591static int
592long_compare(a, b)
593 longobject *a, *b;
594{
595 int sign;
596
Guido van Rossumc6913e71991-11-19 20:26:46 +0000597 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000598 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000599 sign = 0;
600 else
601 sign = a->ob_size - b->ob_size;
602 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000603 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000604 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000605 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
606 ;
607 if (i < 0)
608 sign = 0;
609 else
610 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
611 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000612 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000613}
614
615/* Add the absolute values of two long integers. */
616
617static longobject *x_add PROTO((longobject *, longobject *));
618static longobject *
619x_add(a, b)
620 longobject *a, *b;
621{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000622 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000623 longobject *z;
624 int i;
625 digit carry = 0;
626
627 /* Ensure a is the larger of the two: */
628 if (size_a < size_b) {
629 { longobject *temp = a; a = b; b = temp; }
630 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
631 }
632 z = alloclongobject(size_a+1);
633 if (z == NULL)
634 return NULL;
635 for (i = 0; i < size_b; ++i) {
636 carry += a->ob_digit[i] + b->ob_digit[i];
637 z->ob_digit[i] = carry & MASK;
638 /* The following assumes unsigned shifts don't
639 propagate the sign bit. */
640 carry >>= SHIFT;
641 }
642 for (; i < size_a; ++i) {
643 carry += a->ob_digit[i];
644 z->ob_digit[i] = carry & MASK;
645 carry >>= SHIFT;
646 }
647 z->ob_digit[i] = carry;
648 return long_normalize(z);
649}
650
651/* Subtract the absolute values of two integers. */
652
653static longobject *x_sub PROTO((longobject *, longobject *));
654static longobject *
655x_sub(a, b)
656 longobject *a, *b;
657{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000658 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000659 longobject *z;
660 int i;
661 int sign = 1;
662 digit borrow = 0;
663
664 /* Ensure a is the larger of the two: */
665 if (size_a < size_b) {
666 sign = -1;
667 { longobject *temp = a; a = b; b = temp; }
668 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
669 }
670 else if (size_a == size_b) {
671 /* Find highest digit where a and b differ: */
672 i = size_a;
673 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
674 ;
675 if (i < 0)
676 return alloclongobject(0);
677 if (a->ob_digit[i] < b->ob_digit[i]) {
678 sign = -1;
679 { longobject *temp = a; a = b; b = temp; }
680 }
681 size_a = size_b = i+1;
682 }
683 z = alloclongobject(size_a);
684 if (z == NULL)
685 return NULL;
686 for (i = 0; i < size_b; ++i) {
687 /* The following assumes unsigned arithmetic
688 works module 2**N for some N>SHIFT. */
689 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
690 z->ob_digit[i] = borrow & MASK;
691 borrow >>= SHIFT;
692 borrow &= 1; /* Keep only one sign bit */
693 }
694 for (; i < size_a; ++i) {
695 borrow = a->ob_digit[i] - borrow;
696 z->ob_digit[i] = borrow & MASK;
697 borrow >>= SHIFT;
698 }
699 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000700 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000701 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000702 return long_normalize(z);
703}
704
705static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000706long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000707 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000708 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000709{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000710 longobject *z;
711
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000712 if (a->ob_size < 0) {
713 if (b->ob_size < 0) {
714 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000715 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000716 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000717 }
718 else
719 z = x_sub(b, a);
720 }
721 else {
722 if (b->ob_size < 0)
723 z = x_sub(a, b);
724 else
725 z = x_add(a, b);
726 }
727 return (object *)z;
728}
729
730static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000731long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000732 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000733 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000734{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000735 longobject *z;
736
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000737 if (a->ob_size < 0) {
738 if (b->ob_size < 0)
739 z = x_sub(a, b);
740 else
741 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000742 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000743 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000744 }
745 else {
746 if (b->ob_size < 0)
747 z = x_add(a, b);
748 else
749 z = x_sub(a, b);
750 }
751 return (object *)z;
752}
753
754static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000755long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000756 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000757 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000758{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000759 int size_a;
760 int size_b;
761 longobject *z;
762 int i;
763
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000764 size_a = ABS(a->ob_size);
765 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000766 z = alloclongobject(size_a + size_b);
767 if (z == NULL)
768 return NULL;
769 for (i = 0; i < z->ob_size; ++i)
770 z->ob_digit[i] = 0;
771 for (i = 0; i < size_a; ++i) {
772 twodigits carry = 0;
773 twodigits f = a->ob_digit[i];
774 int j;
775
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000776 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000777 DECREF(z);
778 err_set(KeyboardInterrupt);
779 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000780 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000781 for (j = 0; j < size_b; ++j) {
782 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
783 z->ob_digit[i+j] = carry & MASK;
784 carry >>= SHIFT;
785 }
786 for (; carry != 0; ++j) {
787 assert(i+j < z->ob_size);
788 carry += z->ob_digit[i+j];
789 z->ob_digit[i+j] = carry & MASK;
790 carry >>= SHIFT;
791 }
792 }
793 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000794 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000795 if (b->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000796 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000797 return (object *) long_normalize(z);
798}
799
Guido van Rossume32e0141992-01-19 16:31:05 +0000800/* The / and % operators are now defined in terms of divmod().
801 The expression a mod b has the value a - b*floor(a/b).
802 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000803 |a| by |b|, with the sign of a. This is also expressed
804 as a - b*trunc(a/b), if trunc truncates towards zero.
805 Some examples:
806 a b a rem b a mod b
807 13 10 3 3
808 -13 10 -3 7
809 13 -10 3 -7
810 -13 -10 -3 -3
811 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000812 have different signs. We then subtract one from the 'div'
813 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000814
Guido van Rossume32e0141992-01-19 16:31:05 +0000815static int l_divmod PROTO((longobject *, longobject *,
816 longobject **, longobject **));
817static int
818l_divmod(v, w, pdiv, pmod)
819 longobject *v;
820 longobject *w;
821 longobject **pdiv;
822 longobject **pmod;
823{
824 longobject *div, *mod;
825
826 if (long_divrem(v, w, &div, &mod) < 0)
827 return -1;
828 if (mod->ob_size < 0 && w->ob_size > 0 ||
829 mod->ob_size > 0 && w->ob_size < 0) {
830 longobject *temp;
831 longobject *one;
832 temp = (longobject *) long_add(mod, w);
833 DECREF(mod);
834 mod = temp;
835 if (mod == NULL) {
836 DECREF(div);
837 return -1;
838 }
839 one = (longobject *) newlongobject(1L);
840 if (one == NULL ||
841 (temp = (longobject *) long_sub(div, one)) == NULL) {
842 DECREF(mod);
843 DECREF(div);
844 return -1;
845 }
846 DECREF(div);
847 div = temp;
848 }
849 *pdiv = div;
850 *pmod = mod;
851 return 0;
852}
853
854static object *
855long_div(v, w)
856 longobject *v;
857 longobject *w;
858{
859 longobject *div, *mod;
860 if (l_divmod(v, w, &div, &mod) < 0)
861 return NULL;
862 DECREF(mod);
863 return (object *)div;
864}
865
866static object *
867long_mod(v, w)
868 longobject *v;
869 longobject *w;
870{
871 longobject *div, *mod;
872 if (l_divmod(v, w, &div, &mod) < 0)
873 return NULL;
874 DECREF(div);
875 return (object *)mod;
876}
877
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000878static object *
879long_divmod(v, w)
880 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000881 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000882{
883 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000884 longobject *div, *mod;
885 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000886 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000887 z = newtupleobject(2);
888 if (z != NULL) {
889 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000890 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000891 }
892 else {
893 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000894 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000895 }
896 return z;
897}
898
899static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000900long_pow(a, b)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000901 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000902 longobject *b;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000903{
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000904 longobject *z;
905 int size_b, i;
906
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000907 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000908 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000909 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000910 return NULL;
911 }
912
913 z = (longobject *)newlongobject(1L);
914
915 INCREF(a);
916 for (i = 0; i < size_b; ++i) {
917 digit bi = b->ob_digit[i];
918 int j;
919
920 for (j = 0; j < SHIFT; ++j) {
921 longobject *temp;
922
923 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000924 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000925 DECREF(z);
926 z = temp;
927 if (z == NULL)
928 break;
929 }
930 bi >>= 1;
931 if (bi == 0 && i+1 == size_b)
932 break;
Guido van Rossume32e0141992-01-19 16:31:05 +0000933 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000934 DECREF(a);
935 a = temp;
936 if (a == NULL) {
937 DECREF(z);
938 z = NULL;
939 break;
940 }
941 }
942 if (a == NULL)
943 break;
944 }
945 XDECREF(a);
946 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000947}
948
949static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +0000950long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000951 longobject *v;
952{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000953 /* Implement ~x as -(x+1) */
954 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +0000955 longobject *w;
956 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000957 if (w == NULL)
958 return NULL;
959 x = (longobject *) long_add(v, w);
960 DECREF(w);
961 if (x == NULL)
962 return NULL;
963 if (x->ob_size != 0)
964 x->ob_size = -(x->ob_size);
965 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000966}
967
968static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +0000969long_pos(v)
970 longobject *v;
971{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000972 INCREF(v);
973 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000974}
975
976static object *
977long_neg(v)
978 longobject *v;
979{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000980 longobject *z;
981 int i, n;
982 n = ABS(v->ob_size);
983 if (n == 0) {
984 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +0000985 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000986 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000987 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000988 z = alloclongobject(ABS(n));
989 if (z == NULL)
990 return NULL;
991 for (i = 0; i < n; i++)
992 z->ob_digit[i] = v->ob_digit[i];
993 z->ob_size = -(v->ob_size);
994 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000995}
996
997static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000998long_abs(v)
999 longobject *v;
1000{
1001 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001002 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001003 else {
1004 INCREF(v);
1005 return (object *)v;
1006 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001007}
1008
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001009static int
1010long_nonzero(v)
1011 longobject *v;
1012{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001013 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001014}
1015
1016static object *
1017long_rshift(a, b)
1018 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001019 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001020{
1021 longobject *z;
1022 long shiftby;
1023 int newsize, wordshift, loshift, hishift, i, j;
1024 digit lomask, himask;
1025
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001026 if (a->ob_size < 0) {
1027 /* Right shifting negative numbers is harder */
1028 longobject *a1, *a2, *a3;
1029 a1 = (longobject *) long_invert(a);
1030 if (a1 == NULL) return NULL;
1031 a2 = (longobject *) long_rshift(a1, b);
1032 DECREF(a1);
1033 if (a2 == NULL) return NULL;
1034 a3 = (longobject *) long_invert(a2);
1035 DECREF(a2);
1036 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001037 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001038
1039 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001040 if (shiftby == -1L && err_occurred())
1041 return NULL;
1042 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001043 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001044 return NULL;
1045 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001046 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001047 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001048 if (newsize <= 0) {
1049 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001050 return (object *)z;
1051 }
1052 loshift = shiftby % SHIFT;
1053 hishift = SHIFT - loshift;
1054 lomask = ((digit)1 << hishift) - 1;
1055 himask = MASK ^ lomask;
1056 z = alloclongobject(newsize);
1057 if (z == NULL)
1058 return NULL;
1059 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001060 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001061 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1062 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1063 if (i+1 < newsize)
1064 z->ob_digit[i] |=
1065 (a->ob_digit[j+1] << hishift) & himask;
1066 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001067 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001068}
1069
1070static object *
1071long_lshift(a, b)
1072 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001073 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001074{
1075 longobject *z;
1076 long shiftby;
1077 int newsize, wordshift, loshift, hishift, i, j;
1078 digit lomask, himask;
1079
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001080 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001081 if (shiftby == -1L && err_occurred())
1082 return NULL;
1083 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001084 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001085 return NULL;
1086 }
1087 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001088 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001089 return NULL;
1090 }
1091 if (shiftby % SHIFT == 0) {
1092 wordshift = shiftby / SHIFT;
1093 loshift = 0;
1094 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001095 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001096 lomask = MASK;
1097 himask = 0;
1098 }
1099 else {
1100 wordshift = shiftby / SHIFT + 1;
1101 loshift = SHIFT - shiftby%SHIFT;
1102 hishift = shiftby % SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001103 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001104 lomask = ((digit)1 << hishift) - 1;
1105 himask = MASK ^ lomask;
1106 }
1107 z = alloclongobject(newsize);
1108 if (z == NULL)
1109 return NULL;
1110 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001111 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001112 for (i = 0; i < wordshift; i++)
1113 z->ob_digit[i] = 0;
1114 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1115 if (i > 0)
1116 z->ob_digit[i-1] |=
1117 (a->ob_digit[j] << hishift) & himask;
1118 z->ob_digit[i] =
1119 (a->ob_digit[j] >> loshift) & lomask;
1120 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001121 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001122}
1123
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001124
1125/* Bitwise and/xor/or operations */
1126
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001127#define MAX(x, y) ((x) < (y) ? (y) : (x))
1128#define MIN(x, y) ((x) > (y) ? (y) : (x))
1129
Guido van Rossume32e0141992-01-19 16:31:05 +00001130static object *long_bitwise PROTO((longobject *, int, longobject *));
1131static object *
1132long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001133 longobject *a;
1134 int op; /* '&', '|', '^' */
1135 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001136{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001137 digit maska, maskb; /* 0 or MASK */
1138 int negz;
1139 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001140 longobject *z;
1141 int i;
Guido van Rossum8b27d921992-03-27 17:27:05 +00001142 digit diga, digb;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001143 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001144
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001145 if (a->ob_size < 0) {
1146 a = (longobject *) long_invert(a);
1147 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001148 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001149 else {
1150 INCREF(a);
1151 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001152 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001153 if (b->ob_size < 0) {
1154 b = (longobject *) long_invert(b);
1155 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001156 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001157 else {
1158 INCREF(b);
1159 maskb = 0;
1160 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001161
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001162 size_a = a->ob_size;
1163 size_b = b->ob_size;
1164 size_z = MAX(size_a, size_b);
1165 z = alloclongobject(size_z);
1166 if (a == NULL || b == NULL || z == NULL) {
1167 XDECREF(a);
1168 XDECREF(b);
1169 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001170 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001171 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001172
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001173 negz = 0;
1174 switch (op) {
1175 case '^':
1176 if (maska != maskb) {
1177 maska ^= MASK;
1178 negz = -1;
1179 }
1180 break;
1181 case '&':
1182 if (maska && maskb) {
1183 op = '|';
1184 maska ^= MASK;
1185 maskb ^= MASK;
1186 negz = -1;
1187 }
1188 break;
1189 case '|':
1190 if (maska || maskb) {
1191 op = '&';
1192 maska ^= MASK;
1193 maskb ^= MASK;
1194 negz = -1;
1195 }
1196 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001197 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001198
1199 for (i = 0; i < size_z; ++i) {
1200 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1201 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1202 switch (op) {
1203 case '&': z->ob_digit[i] = diga & digb; break;
1204 case '|': z->ob_digit[i] = diga | digb; break;
1205 case '^': z->ob_digit[i] = diga ^ digb; break;
1206 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001207 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001208
1209 DECREF(a);
1210 DECREF(b);
1211 z = long_normalize(z);
1212 if (negz == 0)
1213 return (object *) z;
1214 v = long_invert(z);
1215 DECREF(z);
1216 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001217}
1218
Guido van Rossumc6913e71991-11-19 20:26:46 +00001219static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001220long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001221 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001222 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001223{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001224 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001225}
1226
1227static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001228long_xor(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001229 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001230 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001231{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001232 return long_bitwise(a, '^', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001233}
1234
1235static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001236long_or(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001237 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001238 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001239{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001240 return long_bitwise(a, '|', b);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001241}
1242
Guido van Rossume6eefc21992-08-14 12:06:52 +00001243int
1244long_coerce(pv, pw)
1245 object **pv;
1246 object **pw;
1247{
1248 if (is_intobject(*pw)) {
1249 *pw = newlongobject(getintvalue(*pw));
1250 INCREF(*pv);
1251 return 0;
1252 }
1253 return 1; /* Can't do it */
1254}
1255
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001256static object *
1257long_int(v)
1258 object *v;
1259{
1260 long x;
1261 x = getlongvalue(v);
1262 if (err_occurred())
1263 return NULL;
1264 return newintobject(x);
1265}
1266
1267static object *
1268long_long(v)
1269 object *v;
1270{
1271 INCREF(v);
1272 return v;
1273}
1274
1275static object *
1276long_float(v)
1277 object *v;
1278{
1279 return newfloatobject(dgetlongvalue(v));
1280}
1281
1282static object *
1283long_oct(v)
1284 object *v;
1285{
1286 return long_format(v, 8);
1287}
1288
1289static object *
1290long_hex(v)
1291 object *v;
1292{
1293 return long_format(v, 16);
1294}
1295
1296
Guido van Rossum8b27d921992-03-27 17:27:05 +00001297#define UF (object* (*) FPROTO((object *))) /* Unary function */
1298#define BF (object* (*) FPROTO((object *, object *))) /* Binary function */
1299#define IF (int (*) FPROTO((object *))) /* Int function */
1300
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001301static number_methods long_as_number = {
Guido van Rossum8b27d921992-03-27 17:27:05 +00001302 BF long_add, /*nb_add*/
1303 BF long_sub, /*nb_subtract*/
1304 BF long_mul, /*nb_multiply*/
1305 BF long_div, /*nb_divide*/
1306 BF long_mod, /*nb_remainder*/
1307 BF long_divmod, /*nb_divmod*/
1308 BF long_pow, /*nb_power*/
1309 UF long_neg, /*nb_negative*/
1310 UF long_pos, /*tp_positive*/
1311 UF long_abs, /*tp_absolute*/
1312 IF long_nonzero,/*tp_nonzero*/
1313 UF long_invert, /*nb_invert*/
1314 BF long_lshift, /*nb_lshift*/
1315 BF long_rshift, /*nb_rshift*/
1316 BF long_and, /*nb_and*/
1317 BF long_xor, /*nb_xor*/
1318 BF long_or, /*nb_or*/
Guido van Rossume6eefc21992-08-14 12:06:52 +00001319 (int (*) FPROTO((object **, object **)))
1320 long_coerce, /*nb_coerce*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001321 UF long_int, /*nb_int*/
1322 UF long_long, /*nb_long*/
1323 UF long_float, /*nb_float*/
1324 UF long_oct, /*nb_oct*/
1325 UF long_hex, /*nb_hex*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001326};
1327
1328typeobject Longtype = {
1329 OB_HEAD_INIT(&Typetype)
1330 0,
1331 "long int",
1332 sizeof(longobject) - sizeof(digit),
1333 sizeof(digit),
1334 long_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001335 0, /*tp_print*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001336 0, /*tp_getattr*/
1337 0, /*tp_setattr*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001338 (int (*) FPROTO((object *, object *)))
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001339 long_compare, /*tp_compare*/
1340 long_repr, /*tp_repr*/
1341 &long_as_number,/*tp_as_number*/
1342 0, /*tp_as_sequence*/
1343 0, /*tp_as_mapping*/
1344};