blob: b1e98340d778fd41d980564663118e25b15b6606 [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"
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 Rossum3d3037d1991-10-24 14:55:57 +0000325 if (base == 8)
326 *--p = '0';
327 else if (base == 16) {
328 *--p = 'x';
329 *--p = '0';
330 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000331 else if (base != 10) {
332 *--p = '#';
333 *--p = '0' + base%10;
334 if (base > 10)
335 *--p = '0' + base/10;
336 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000337 if (sign)
338 *--p = sign;
339 if (p != GETSTRINGVALUE(str)) {
340 char *q = GETSTRINGVALUE(str);
341 assert(p > q);
342 do {
343 } while ((*q++ = *p++) != '\0');
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000344 q--;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000345 resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
346 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000347 return (object *)str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000348}
349
350/* Convert a string to a long int object, in a given base.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000351 Base zero implies a default depending on the number.
352 External linkage: used in compile.c for literals. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000353
354object *
355long_scan(str, base)
356 char *str;
357 int base;
358{
359 int sign = 1;
360 longobject *z;
361
362 assert(base == 0 || base >= 2 && base <= 36);
363 if (*str == '+')
364 ++str;
365 else if (*str == '-') {
366 ++str;
367 sign = -1;
368 }
369 if (base == 0) {
370 if (str[0] != '0')
371 base = 10;
372 else if (str[1] == 'x' || str[1] == 'X')
373 base = 16;
374 else
375 base = 8;
376 }
377 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
378 str += 2;
379 z = alloclongobject(0);
380 for ( ; z != NULL; ++str) {
381 int k = -1;
382 longobject *temp;
383
384 if (*str <= '9')
385 k = *str - '0';
386 else if (*str >= 'a')
387 k = *str - 'a' + 10;
388 else if (*str >= 'A')
389 k = *str - 'A' + 10;
390 if (k < 0 || k >= base)
391 break;
392 temp = muladd1(z, (digit)base, (digit)k);
393 DECREF(z);
394 z = temp;
395 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000396 if (sign < 0 && z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000397 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000398 return (object *) z;
399}
400
401static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
Guido van Rossumc6913e71991-11-19 20:26:46 +0000402static object *long_pos PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000403static long_divrem PROTO((longobject *, longobject *,
404 longobject **, longobject **));
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000405
406/* Long division with remainder, top-level routine */
407
Guido van Rossume32e0141992-01-19 16:31:05 +0000408static int
409long_divrem(a, b, pdiv, prem)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000410 longobject *a, *b;
Guido van Rossume32e0141992-01-19 16:31:05 +0000411 longobject **pdiv;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000412 longobject **prem;
413{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000414 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000415 longobject *z;
416
417 if (size_b == 0) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000418 err_setstr(ZeroDivisionError, "long division or modulo");
419 return -1;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000420 }
421 if (size_a < size_b ||
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000422 size_a == size_b &&
423 a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000424 /* |a| < |b|. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000425 *pdiv = alloclongobject(0);
426 INCREF(a);
427 *prem = (longobject *) a;
428 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000429 }
430 if (size_b == 1) {
431 digit rem = 0;
432 z = divrem1(a, b->ob_digit[0], &rem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000433 if (z == NULL)
434 return -1;
435 *prem = (longobject *) newlongobject((long)rem);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000436 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000437 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000438 z = x_divrem(a, b, prem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000439 if (z == NULL)
440 return -1;
441 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000442 /* Set the signs.
443 The quotient z has the sign of a*b;
444 the remainder r has the sign of a,
445 so a = b*z + r. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000446 if ((a->ob_size < 0) != (b->ob_size < 0))
447 z->ob_size = -(z->ob_size);
448 if (a->ob_size < 0 && (*prem)->ob_size != 0)
449 (*prem)->ob_size = -((*prem)->ob_size);
450 *pdiv = z;
451 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000452}
453
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000454/* Unsigned long division with remainder -- the algorithm */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000455
456static longobject *
457x_divrem(v1, w1, prem)
458 longobject *v1, *w1;
459 longobject **prem;
460{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000461 int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000462 digit d = (twodigits)BASE / (w1->ob_digit[size_w-1] + 1);
463 longobject *v = mul1(v1, d);
464 longobject *w = mul1(w1, d);
465 longobject *a;
466 int j, k;
467
468 if (v == NULL || w == NULL) {
469 XDECREF(v);
470 XDECREF(w);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000471 return NULL;
472 }
473
474 assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000475 assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000476 assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000477
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000478 size_v = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000479 a = alloclongobject(size_v - size_w + 1);
480
481 for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
482 digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
483 twodigits q;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000484 stwodigits carry = 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000485 int i;
486
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000487 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000488 DECREF(a);
489 a = NULL;
490 err_set(KeyboardInterrupt);
491 break;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000492 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000493 if (vj == w->ob_digit[size_w-1])
494 q = MASK;
495 else
496 q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
497 w->ob_digit[size_w-1];
498
499 while (w->ob_digit[size_w-2]*q >
500 ((
501 ((twodigits)vj << SHIFT)
502 + v->ob_digit[j-1]
503 - q*w->ob_digit[size_w-1]
504 ) << SHIFT)
505 + v->ob_digit[j-2])
506 --q;
507
508 for (i = 0; i < size_w && i+k < size_v; ++i) {
509 twodigits z = w->ob_digit[i] * q;
510 digit zz = z >> SHIFT;
511 carry += v->ob_digit[i+k] - z + ((twodigits)zz << SHIFT);
512 v->ob_digit[i+k] = carry & MASK;
513 carry = (carry >> SHIFT) - zz;
514 }
515
516 if (i+k < size_v) {
517 carry += v->ob_digit[i+k];
518 v->ob_digit[i+k] = 0;
519 }
520
521 if (carry == 0)
522 a->ob_digit[k] = q;
523 else {
524 assert(carry == -1);
525 a->ob_digit[k] = q-1;
526 carry = 0;
527 for (i = 0; i < size_w && i+k < size_v; ++i) {
528 carry += v->ob_digit[i+k] + w->ob_digit[i];
529 v->ob_digit[i+k] = carry & MASK;
530 carry >>= SHIFT;
531 }
532 }
533 } /* for j, k */
534
Guido van Rossume32e0141992-01-19 16:31:05 +0000535 if (a != NULL) {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000536 a = long_normalize(a);
Guido van Rossume32e0141992-01-19 16:31:05 +0000537 *prem = divrem1(v, d, &d);
538 /* d receives the (unused) remainder */
539 if (*prem == NULL) {
540 DECREF(a);
541 a = NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000542 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000543 }
544 DECREF(v);
545 DECREF(w);
546 return a;
547}
548
549/* Methods */
550
Guido van Rossume32e0141992-01-19 16:31:05 +0000551/* Forward */
552static void long_dealloc PROTO((longobject *));
553static int long_print PROTO((longobject *, FILE *, int));
554static object *long_repr PROTO((longobject *));
555static int long_compare PROTO((longobject *, longobject *));
556
557static object *long_add PROTO((longobject *, longobject *));
558static object *long_sub PROTO((longobject *, longobject *));
559static object *long_mul PROTO((longobject *, longobject *));
560static object *long_div PROTO((longobject *, longobject *));
561static object *long_mod PROTO((longobject *, longobject *));
562static object *long_divmod PROTO((longobject *, longobject *));
563static object *long_pow PROTO((longobject *, longobject *));
564static object *long_neg PROTO((longobject *));
565static object *long_pos PROTO((longobject *));
566static object *long_abs PROTO((longobject *));
567static int long_nonzero PROTO((longobject *));
568static object *long_invert PROTO((longobject *));
569static object *long_lshift PROTO((longobject *, longobject *));
570static object *long_rshift PROTO((longobject *, longobject *));
571static object *long_and PROTO((longobject *, longobject *));
572static object *long_xor PROTO((longobject *, longobject *));
573static object *long_or PROTO((longobject *, longobject *));
574
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000575static void
576long_dealloc(v)
577 longobject *v;
578{
579 DEL(v);
580}
581
Guido van Rossum90933611991-06-07 16:10:43 +0000582static int
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000583long_print(v, fp, flags)
584 longobject *v;
585 FILE *fp;
586 int flags;
587{
Guido van Rossume32e0141992-01-19 16:31:05 +0000588 stringobject *str = (stringobject *) long_format((object *)v, 10);
Guido van Rossum90933611991-06-07 16:10:43 +0000589 if (str == NULL)
590 return -1;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000591 fprintf(fp, "%s", GETSTRINGVALUE(str));
Guido van Rossum90933611991-06-07 16:10:43 +0000592 DECREF(str);
593 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000594}
595
596static object *
597long_repr(v)
598 longobject *v;
599{
Guido van Rossume32e0141992-01-19 16:31:05 +0000600 return long_format((object *)v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000601}
602
603static int
604long_compare(a, b)
605 longobject *a, *b;
606{
607 int sign;
608
Guido van Rossumc6913e71991-11-19 20:26:46 +0000609 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000610 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000611 sign = 0;
612 else
613 sign = a->ob_size - b->ob_size;
614 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000615 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000616 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000617 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
618 ;
619 if (i < 0)
620 sign = 0;
621 else
622 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
623 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000624 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000625}
626
627/* Add the absolute values of two long integers. */
628
629static longobject *x_add PROTO((longobject *, longobject *));
630static longobject *
631x_add(a, b)
632 longobject *a, *b;
633{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000634 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000635 longobject *z;
636 int i;
637 digit carry = 0;
638
639 /* Ensure a is the larger of the two: */
640 if (size_a < size_b) {
641 { longobject *temp = a; a = b; b = temp; }
642 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
643 }
644 z = alloclongobject(size_a+1);
645 if (z == NULL)
646 return NULL;
647 for (i = 0; i < size_b; ++i) {
648 carry += a->ob_digit[i] + b->ob_digit[i];
649 z->ob_digit[i] = carry & MASK;
650 /* The following assumes unsigned shifts don't
651 propagate the sign bit. */
652 carry >>= SHIFT;
653 }
654 for (; i < size_a; ++i) {
655 carry += a->ob_digit[i];
656 z->ob_digit[i] = carry & MASK;
657 carry >>= SHIFT;
658 }
659 z->ob_digit[i] = carry;
660 return long_normalize(z);
661}
662
663/* Subtract the absolute values of two integers. */
664
665static longobject *x_sub PROTO((longobject *, longobject *));
666static longobject *
667x_sub(a, b)
668 longobject *a, *b;
669{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000670 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000671 longobject *z;
672 int i;
673 int sign = 1;
674 digit borrow = 0;
675
676 /* Ensure a is the larger of the two: */
677 if (size_a < size_b) {
678 sign = -1;
679 { longobject *temp = a; a = b; b = temp; }
680 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
681 }
682 else if (size_a == size_b) {
683 /* Find highest digit where a and b differ: */
684 i = size_a;
685 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
686 ;
687 if (i < 0)
688 return alloclongobject(0);
689 if (a->ob_digit[i] < b->ob_digit[i]) {
690 sign = -1;
691 { longobject *temp = a; a = b; b = temp; }
692 }
693 size_a = size_b = i+1;
694 }
695 z = alloclongobject(size_a);
696 if (z == NULL)
697 return NULL;
698 for (i = 0; i < size_b; ++i) {
699 /* The following assumes unsigned arithmetic
700 works module 2**N for some N>SHIFT. */
701 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
702 z->ob_digit[i] = borrow & MASK;
703 borrow >>= SHIFT;
704 borrow &= 1; /* Keep only one sign bit */
705 }
706 for (; i < size_a; ++i) {
707 borrow = a->ob_digit[i] - borrow;
708 z->ob_digit[i] = borrow & MASK;
709 borrow >>= SHIFT;
710 }
711 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000712 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000713 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000714 return long_normalize(z);
715}
716
717static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000718long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000719 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000720 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000721{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000722 longobject *z;
723
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000724 if (a->ob_size < 0) {
725 if (b->ob_size < 0) {
726 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000727 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000728 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000729 }
730 else
731 z = x_sub(b, a);
732 }
733 else {
734 if (b->ob_size < 0)
735 z = x_sub(a, b);
736 else
737 z = x_add(a, b);
738 }
739 return (object *)z;
740}
741
742static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000743long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000744 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000745 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000746{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000747 longobject *z;
748
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000749 if (a->ob_size < 0) {
750 if (b->ob_size < 0)
751 z = x_sub(a, b);
752 else
753 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000754 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000755 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000756 }
757 else {
758 if (b->ob_size < 0)
759 z = x_add(a, b);
760 else
761 z = x_sub(a, b);
762 }
763 return (object *)z;
764}
765
766static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000767long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000768 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000769 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000770{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000771 int size_a;
772 int size_b;
773 longobject *z;
774 int i;
775
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000776 size_a = ABS(a->ob_size);
777 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000778 z = alloclongobject(size_a + size_b);
779 if (z == NULL)
780 return NULL;
781 for (i = 0; i < z->ob_size; ++i)
782 z->ob_digit[i] = 0;
783 for (i = 0; i < size_a; ++i) {
784 twodigits carry = 0;
785 twodigits f = a->ob_digit[i];
786 int j;
787
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000788 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000789 DECREF(z);
790 err_set(KeyboardInterrupt);
791 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000792 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000793 for (j = 0; j < size_b; ++j) {
794 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
795 z->ob_digit[i+j] = carry & MASK;
796 carry >>= SHIFT;
797 }
798 for (; carry != 0; ++j) {
799 assert(i+j < z->ob_size);
800 carry += z->ob_digit[i+j];
801 z->ob_digit[i+j] = carry & MASK;
802 carry >>= SHIFT;
803 }
804 }
805 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000806 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000807 if (b->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000808 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000809 return (object *) long_normalize(z);
810}
811
Guido van Rossume32e0141992-01-19 16:31:05 +0000812/* The / and % operators are now defined in terms of divmod().
813 The expression a mod b has the value a - b*floor(a/b).
814 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000815 |a| by |b|, with the sign of a. This is also expressed
816 as a - b*trunc(a/b), if trunc truncates towards zero.
817 Some examples:
818 a b a rem b a mod b
819 13 10 3 3
820 -13 10 -3 7
821 13 -10 3 -7
822 -13 -10 -3 -3
823 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000824 have different signs. We then subtract one from the 'div'
825 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000826
Guido van Rossume32e0141992-01-19 16:31:05 +0000827static int l_divmod PROTO((longobject *, longobject *,
828 longobject **, longobject **));
829static int
830l_divmod(v, w, pdiv, pmod)
831 longobject *v;
832 longobject *w;
833 longobject **pdiv;
834 longobject **pmod;
835{
836 longobject *div, *mod;
837
838 if (long_divrem(v, w, &div, &mod) < 0)
839 return -1;
840 if (mod->ob_size < 0 && w->ob_size > 0 ||
841 mod->ob_size > 0 && w->ob_size < 0) {
842 longobject *temp;
843 longobject *one;
844 temp = (longobject *) long_add(mod, w);
845 DECREF(mod);
846 mod = temp;
847 if (mod == NULL) {
848 DECREF(div);
849 return -1;
850 }
851 one = (longobject *) newlongobject(1L);
852 if (one == NULL ||
853 (temp = (longobject *) long_sub(div, one)) == NULL) {
854 DECREF(mod);
855 DECREF(div);
856 return -1;
857 }
858 DECREF(div);
859 div = temp;
860 }
861 *pdiv = div;
862 *pmod = mod;
863 return 0;
864}
865
866static object *
867long_div(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(mod);
875 return (object *)div;
876}
877
878static object *
879long_mod(v, w)
880 longobject *v;
881 longobject *w;
882{
883 longobject *div, *mod;
884 if (l_divmod(v, w, &div, &mod) < 0)
885 return NULL;
886 DECREF(div);
887 return (object *)mod;
888}
889
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000890static object *
891long_divmod(v, w)
892 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000893 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000894{
895 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000896 longobject *div, *mod;
897 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000898 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000899 z = newtupleobject(2);
900 if (z != NULL) {
901 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000902 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000903 }
904 else {
905 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000906 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000907 }
908 return z;
909}
910
911static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000912long_pow(a, b)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000913 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000914 longobject *b;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000915{
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000916 longobject *z;
917 int size_b, i;
918
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000919 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000920 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000921 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000922 return NULL;
923 }
924
925 z = (longobject *)newlongobject(1L);
926
927 INCREF(a);
928 for (i = 0; i < size_b; ++i) {
929 digit bi = b->ob_digit[i];
930 int j;
931
932 for (j = 0; j < SHIFT; ++j) {
933 longobject *temp;
934
935 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000936 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000937 DECREF(z);
938 z = temp;
939 if (z == NULL)
940 break;
941 }
942 bi >>= 1;
943 if (bi == 0 && i+1 == size_b)
944 break;
Guido van Rossume32e0141992-01-19 16:31:05 +0000945 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000946 DECREF(a);
947 a = temp;
948 if (a == NULL) {
949 DECREF(z);
950 z = NULL;
951 break;
952 }
953 }
954 if (a == NULL)
955 break;
956 }
957 XDECREF(a);
958 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000959}
960
961static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +0000962long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000963 longobject *v;
964{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000965 /* Implement ~x as -(x+1) */
966 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +0000967 longobject *w;
968 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000969 if (w == NULL)
970 return NULL;
971 x = (longobject *) long_add(v, w);
972 DECREF(w);
973 if (x == NULL)
974 return NULL;
975 if (x->ob_size != 0)
976 x->ob_size = -(x->ob_size);
977 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000978}
979
980static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +0000981long_pos(v)
982 longobject *v;
983{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000984 INCREF(v);
985 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000986}
987
988static object *
989long_neg(v)
990 longobject *v;
991{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000992 longobject *z;
993 int i, n;
994 n = ABS(v->ob_size);
995 if (n == 0) {
996 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +0000997 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000998 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000999 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001000 z = alloclongobject(ABS(n));
1001 if (z == NULL)
1002 return NULL;
1003 for (i = 0; i < n; i++)
1004 z->ob_digit[i] = v->ob_digit[i];
1005 z->ob_size = -(v->ob_size);
1006 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001007}
1008
1009static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001010long_abs(v)
1011 longobject *v;
1012{
1013 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001014 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001015 else {
1016 INCREF(v);
1017 return (object *)v;
1018 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001019}
1020
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001021static int
1022long_nonzero(v)
1023 longobject *v;
1024{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001025 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001026}
1027
1028static object *
1029long_rshift(a, b)
1030 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001031 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001032{
1033 longobject *z;
1034 long shiftby;
1035 int newsize, wordshift, loshift, hishift, i, j;
1036 digit lomask, himask;
1037
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001038 if (a->ob_size < 0) {
1039 /* Right shifting negative numbers is harder */
1040 longobject *a1, *a2, *a3;
1041 a1 = (longobject *) long_invert(a);
1042 if (a1 == NULL) return NULL;
1043 a2 = (longobject *) long_rshift(a1, b);
1044 DECREF(a1);
1045 if (a2 == NULL) return NULL;
1046 a3 = (longobject *) long_invert(a2);
1047 DECREF(a2);
1048 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001049 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001050
1051 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001052 if (shiftby == -1L && err_occurred())
1053 return NULL;
1054 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001055 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001056 return NULL;
1057 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001058 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001059 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001060 if (newsize <= 0) {
1061 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001062 return (object *)z;
1063 }
1064 loshift = shiftby % SHIFT;
1065 hishift = SHIFT - loshift;
1066 lomask = ((digit)1 << hishift) - 1;
1067 himask = MASK ^ lomask;
1068 z = alloclongobject(newsize);
1069 if (z == NULL)
1070 return NULL;
1071 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001072 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001073 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1074 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1075 if (i+1 < newsize)
1076 z->ob_digit[i] |=
1077 (a->ob_digit[j+1] << hishift) & himask;
1078 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001079 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001080}
1081
1082static object *
1083long_lshift(a, b)
1084 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001085 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001086{
1087 longobject *z;
1088 long shiftby;
1089 int newsize, wordshift, loshift, hishift, i, j;
1090 digit lomask, himask;
1091
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001092 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001093 if (shiftby == -1L && err_occurred())
1094 return NULL;
1095 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001096 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001097 return NULL;
1098 }
1099 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001100 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001101 return NULL;
1102 }
1103 if (shiftby % SHIFT == 0) {
1104 wordshift = shiftby / SHIFT;
1105 loshift = 0;
1106 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001107 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001108 lomask = MASK;
1109 himask = 0;
1110 }
1111 else {
1112 wordshift = shiftby / SHIFT + 1;
1113 loshift = SHIFT - shiftby%SHIFT;
1114 hishift = shiftby % SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001115 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001116 lomask = ((digit)1 << hishift) - 1;
1117 himask = MASK ^ lomask;
1118 }
1119 z = alloclongobject(newsize);
1120 if (z == NULL)
1121 return NULL;
1122 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001123 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001124 for (i = 0; i < wordshift; i++)
1125 z->ob_digit[i] = 0;
1126 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1127 if (i > 0)
1128 z->ob_digit[i-1] |=
1129 (a->ob_digit[j] << hishift) & himask;
1130 z->ob_digit[i] =
1131 (a->ob_digit[j] >> loshift) & lomask;
1132 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001133 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001134}
1135
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001136
1137/* Bitwise and/xor/or operations */
1138
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001139#define MAX(x, y) ((x) < (y) ? (y) : (x))
1140#define MIN(x, y) ((x) > (y) ? (y) : (x))
1141
Guido van Rossume32e0141992-01-19 16:31:05 +00001142static object *long_bitwise PROTO((longobject *, int, longobject *));
1143static object *
1144long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001145 longobject *a;
1146 int op; /* '&', '|', '^' */
1147 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001148{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001149 digit maska, maskb; /* 0 or MASK */
1150 int negz;
1151 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001152 longobject *z;
1153 int i;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001154 digit diga, digb, digz;
1155 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001156
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001157 if (a->ob_size < 0) {
1158 a = (longobject *) long_invert(a);
1159 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001160 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001161 else {
1162 INCREF(a);
1163 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001164 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001165 if (b->ob_size < 0) {
1166 b = (longobject *) long_invert(b);
1167 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001168 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001169 else {
1170 INCREF(b);
1171 maskb = 0;
1172 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001173
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001174 size_a = a->ob_size;
1175 size_b = b->ob_size;
1176 size_z = MAX(size_a, size_b);
1177 z = alloclongobject(size_z);
1178 if (a == NULL || b == NULL || z == NULL) {
1179 XDECREF(a);
1180 XDECREF(b);
1181 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001182 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001183 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001184
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001185 negz = 0;
1186 switch (op) {
1187 case '^':
1188 if (maska != maskb) {
1189 maska ^= MASK;
1190 negz = -1;
1191 }
1192 break;
1193 case '&':
1194 if (maska && maskb) {
1195 op = '|';
1196 maska ^= MASK;
1197 maskb ^= MASK;
1198 negz = -1;
1199 }
1200 break;
1201 case '|':
1202 if (maska || maskb) {
1203 op = '&';
1204 maska ^= MASK;
1205 maskb ^= MASK;
1206 negz = -1;
1207 }
1208 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001209 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001210
1211 for (i = 0; i < size_z; ++i) {
1212 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1213 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1214 switch (op) {
1215 case '&': z->ob_digit[i] = diga & digb; break;
1216 case '|': z->ob_digit[i] = diga | digb; break;
1217 case '^': z->ob_digit[i] = diga ^ digb; break;
1218 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001219 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001220
1221 DECREF(a);
1222 DECREF(b);
1223 z = long_normalize(z);
1224 if (negz == 0)
1225 return (object *) z;
1226 v = long_invert(z);
1227 DECREF(z);
1228 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001229}
1230
Guido van Rossumc6913e71991-11-19 20:26:46 +00001231static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001232long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001233 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001234 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001235{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001236 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001237}
1238
1239static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001240long_xor(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001241 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001242 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001243{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001244 return long_bitwise(a, '^', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001245}
1246
1247static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001248long_or(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001249 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001250 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001251{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001252 return long_bitwise(a, '|', b);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001253}
1254
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001255static number_methods long_as_number = {
1256 long_add, /*nb_add*/
1257 long_sub, /*nb_subtract*/
1258 long_mul, /*nb_multiply*/
1259 long_div, /*nb_divide*/
Guido van Rossume32e0141992-01-19 16:31:05 +00001260 long_mod, /*nb_remainder*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001261 long_divmod, /*nb_divmod*/
1262 long_pow, /*nb_power*/
1263 long_neg, /*nb_negative*/
1264 long_pos, /*tp_positive*/
1265 long_abs, /*tp_absolute*/
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001266 long_nonzero, /*tp_nonzero*/
Guido van Rossumc6913e71991-11-19 20:26:46 +00001267 long_invert, /*nb_invert*/
1268 long_lshift, /*nb_lshift*/
1269 long_rshift, /*nb_rshift*/
1270 long_and, /*nb_and*/
1271 long_xor, /*nb_xor*/
1272 long_or, /*nb_or*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001273};
1274
1275typeobject Longtype = {
1276 OB_HEAD_INIT(&Typetype)
1277 0,
1278 "long int",
1279 sizeof(longobject) - sizeof(digit),
1280 sizeof(digit),
1281 long_dealloc, /*tp_dealloc*/
1282 long_print, /*tp_print*/
1283 0, /*tp_getattr*/
1284 0, /*tp_setattr*/
1285 long_compare, /*tp_compare*/
1286 long_repr, /*tp_repr*/
1287 &long_as_number,/*tp_as_number*/
1288 0, /*tp_as_sequence*/
1289 0, /*tp_as_mapping*/
1290};