blob: f9e37650f3281acb16234090fdd5c60a96acc90f [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 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 */
Guido van Rossum8b27d921992-03-27 17:27:05 +0000552static void long_dealloc PROTO((object *));
553static int long_print PROTO((object *, FILE *, int));
554static object *long_repr PROTO((object *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000555static 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)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000577 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000578{
579 DEL(v);
580}
581
Guido van Rossum8b27d921992-03-27 17:27:05 +0000582/* ARGSUSED */
Guido van Rossum90933611991-06-07 16:10:43 +0000583static int
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000584long_print(v, fp, flags)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000585 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000586 FILE *fp;
Guido van Rossum8b27d921992-03-27 17:27:05 +0000587 int flags; /* Not used but required by interface */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000588{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000589 stringobject *str = (stringobject *) long_format(v, 10);
Guido van Rossum90933611991-06-07 16:10:43 +0000590 if (str == NULL)
591 return -1;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000592 fprintf(fp, "%s", GETSTRINGVALUE(str));
Guido van Rossum90933611991-06-07 16:10:43 +0000593 DECREF(str);
594 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000595}
596
597static object *
598long_repr(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000599 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000600{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000601 return long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000602}
603
604static int
605long_compare(a, b)
606 longobject *a, *b;
607{
608 int sign;
609
Guido van Rossumc6913e71991-11-19 20:26:46 +0000610 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000611 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000612 sign = 0;
613 else
614 sign = a->ob_size - b->ob_size;
615 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000616 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000617 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000618 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
619 ;
620 if (i < 0)
621 sign = 0;
622 else
623 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
624 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000625 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000626}
627
628/* Add the absolute values of two long integers. */
629
630static longobject *x_add PROTO((longobject *, longobject *));
631static longobject *
632x_add(a, b)
633 longobject *a, *b;
634{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000635 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000636 longobject *z;
637 int i;
638 digit carry = 0;
639
640 /* Ensure a is the larger of the two: */
641 if (size_a < size_b) {
642 { longobject *temp = a; a = b; b = temp; }
643 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
644 }
645 z = alloclongobject(size_a+1);
646 if (z == NULL)
647 return NULL;
648 for (i = 0; i < size_b; ++i) {
649 carry += a->ob_digit[i] + b->ob_digit[i];
650 z->ob_digit[i] = carry & MASK;
651 /* The following assumes unsigned shifts don't
652 propagate the sign bit. */
653 carry >>= SHIFT;
654 }
655 for (; i < size_a; ++i) {
656 carry += a->ob_digit[i];
657 z->ob_digit[i] = carry & MASK;
658 carry >>= SHIFT;
659 }
660 z->ob_digit[i] = carry;
661 return long_normalize(z);
662}
663
664/* Subtract the absolute values of two integers. */
665
666static longobject *x_sub PROTO((longobject *, longobject *));
667static longobject *
668x_sub(a, b)
669 longobject *a, *b;
670{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000671 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000672 longobject *z;
673 int i;
674 int sign = 1;
675 digit borrow = 0;
676
677 /* Ensure a is the larger of the two: */
678 if (size_a < size_b) {
679 sign = -1;
680 { longobject *temp = a; a = b; b = temp; }
681 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
682 }
683 else if (size_a == size_b) {
684 /* Find highest digit where a and b differ: */
685 i = size_a;
686 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
687 ;
688 if (i < 0)
689 return alloclongobject(0);
690 if (a->ob_digit[i] < b->ob_digit[i]) {
691 sign = -1;
692 { longobject *temp = a; a = b; b = temp; }
693 }
694 size_a = size_b = i+1;
695 }
696 z = alloclongobject(size_a);
697 if (z == NULL)
698 return NULL;
699 for (i = 0; i < size_b; ++i) {
700 /* The following assumes unsigned arithmetic
701 works module 2**N for some N>SHIFT. */
702 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
703 z->ob_digit[i] = borrow & MASK;
704 borrow >>= SHIFT;
705 borrow &= 1; /* Keep only one sign bit */
706 }
707 for (; i < size_a; ++i) {
708 borrow = a->ob_digit[i] - borrow;
709 z->ob_digit[i] = borrow & MASK;
710 borrow >>= SHIFT;
711 }
712 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000713 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000714 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000715 return long_normalize(z);
716}
717
718static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000719long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000720 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000721 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000722{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000723 longobject *z;
724
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000725 if (a->ob_size < 0) {
726 if (b->ob_size < 0) {
727 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000728 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000729 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000730 }
731 else
732 z = x_sub(b, a);
733 }
734 else {
735 if (b->ob_size < 0)
736 z = x_sub(a, b);
737 else
738 z = x_add(a, b);
739 }
740 return (object *)z;
741}
742
743static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000744long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000745 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000746 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000747{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000748 longobject *z;
749
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000750 if (a->ob_size < 0) {
751 if (b->ob_size < 0)
752 z = x_sub(a, b);
753 else
754 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000755 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000756 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000757 }
758 else {
759 if (b->ob_size < 0)
760 z = x_add(a, b);
761 else
762 z = x_sub(a, b);
763 }
764 return (object *)z;
765}
766
767static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000768long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000769 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000770 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000771{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000772 int size_a;
773 int size_b;
774 longobject *z;
775 int i;
776
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000777 size_a = ABS(a->ob_size);
778 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000779 z = alloclongobject(size_a + size_b);
780 if (z == NULL)
781 return NULL;
782 for (i = 0; i < z->ob_size; ++i)
783 z->ob_digit[i] = 0;
784 for (i = 0; i < size_a; ++i) {
785 twodigits carry = 0;
786 twodigits f = a->ob_digit[i];
787 int j;
788
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000789 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000790 DECREF(z);
791 err_set(KeyboardInterrupt);
792 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000793 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000794 for (j = 0; j < size_b; ++j) {
795 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
796 z->ob_digit[i+j] = carry & MASK;
797 carry >>= SHIFT;
798 }
799 for (; carry != 0; ++j) {
800 assert(i+j < z->ob_size);
801 carry += z->ob_digit[i+j];
802 z->ob_digit[i+j] = carry & MASK;
803 carry >>= SHIFT;
804 }
805 }
806 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000807 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000808 if (b->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000809 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000810 return (object *) long_normalize(z);
811}
812
Guido van Rossume32e0141992-01-19 16:31:05 +0000813/* The / and % operators are now defined in terms of divmod().
814 The expression a mod b has the value a - b*floor(a/b).
815 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000816 |a| by |b|, with the sign of a. This is also expressed
817 as a - b*trunc(a/b), if trunc truncates towards zero.
818 Some examples:
819 a b a rem b a mod b
820 13 10 3 3
821 -13 10 -3 7
822 13 -10 3 -7
823 -13 -10 -3 -3
824 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000825 have different signs. We then subtract one from the 'div'
826 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000827
Guido van Rossume32e0141992-01-19 16:31:05 +0000828static int l_divmod PROTO((longobject *, longobject *,
829 longobject **, longobject **));
830static int
831l_divmod(v, w, pdiv, pmod)
832 longobject *v;
833 longobject *w;
834 longobject **pdiv;
835 longobject **pmod;
836{
837 longobject *div, *mod;
838
839 if (long_divrem(v, w, &div, &mod) < 0)
840 return -1;
841 if (mod->ob_size < 0 && w->ob_size > 0 ||
842 mod->ob_size > 0 && w->ob_size < 0) {
843 longobject *temp;
844 longobject *one;
845 temp = (longobject *) long_add(mod, w);
846 DECREF(mod);
847 mod = temp;
848 if (mod == NULL) {
849 DECREF(div);
850 return -1;
851 }
852 one = (longobject *) newlongobject(1L);
853 if (one == NULL ||
854 (temp = (longobject *) long_sub(div, one)) == NULL) {
855 DECREF(mod);
856 DECREF(div);
857 return -1;
858 }
859 DECREF(div);
860 div = temp;
861 }
862 *pdiv = div;
863 *pmod = mod;
864 return 0;
865}
866
867static object *
868long_div(v, w)
869 longobject *v;
870 longobject *w;
871{
872 longobject *div, *mod;
873 if (l_divmod(v, w, &div, &mod) < 0)
874 return NULL;
875 DECREF(mod);
876 return (object *)div;
877}
878
879static object *
880long_mod(v, w)
881 longobject *v;
882 longobject *w;
883{
884 longobject *div, *mod;
885 if (l_divmod(v, w, &div, &mod) < 0)
886 return NULL;
887 DECREF(div);
888 return (object *)mod;
889}
890
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000891static object *
892long_divmod(v, w)
893 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000894 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000895{
896 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000897 longobject *div, *mod;
898 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000899 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000900 z = newtupleobject(2);
901 if (z != NULL) {
902 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000903 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000904 }
905 else {
906 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000907 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000908 }
909 return z;
910}
911
912static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000913long_pow(a, b)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000914 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000915 longobject *b;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000916{
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000917 longobject *z;
918 int size_b, i;
919
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000920 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000921 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000922 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000923 return NULL;
924 }
925
926 z = (longobject *)newlongobject(1L);
927
928 INCREF(a);
929 for (i = 0; i < size_b; ++i) {
930 digit bi = b->ob_digit[i];
931 int j;
932
933 for (j = 0; j < SHIFT; ++j) {
934 longobject *temp;
935
936 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000937 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000938 DECREF(z);
939 z = temp;
940 if (z == NULL)
941 break;
942 }
943 bi >>= 1;
944 if (bi == 0 && i+1 == size_b)
945 break;
Guido van Rossume32e0141992-01-19 16:31:05 +0000946 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000947 DECREF(a);
948 a = temp;
949 if (a == NULL) {
950 DECREF(z);
951 z = NULL;
952 break;
953 }
954 }
955 if (a == NULL)
956 break;
957 }
958 XDECREF(a);
959 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000960}
961
962static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +0000963long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000964 longobject *v;
965{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000966 /* Implement ~x as -(x+1) */
967 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +0000968 longobject *w;
969 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000970 if (w == NULL)
971 return NULL;
972 x = (longobject *) long_add(v, w);
973 DECREF(w);
974 if (x == NULL)
975 return NULL;
976 if (x->ob_size != 0)
977 x->ob_size = -(x->ob_size);
978 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000979}
980
981static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +0000982long_pos(v)
983 longobject *v;
984{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000985 INCREF(v);
986 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000987}
988
989static object *
990long_neg(v)
991 longobject *v;
992{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000993 longobject *z;
994 int i, n;
995 n = ABS(v->ob_size);
996 if (n == 0) {
997 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +0000998 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000999 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001000 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001001 z = alloclongobject(ABS(n));
1002 if (z == NULL)
1003 return NULL;
1004 for (i = 0; i < n; i++)
1005 z->ob_digit[i] = v->ob_digit[i];
1006 z->ob_size = -(v->ob_size);
1007 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001008}
1009
1010static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001011long_abs(v)
1012 longobject *v;
1013{
1014 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001015 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001016 else {
1017 INCREF(v);
1018 return (object *)v;
1019 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001020}
1021
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001022static int
1023long_nonzero(v)
1024 longobject *v;
1025{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001026 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001027}
1028
1029static object *
1030long_rshift(a, b)
1031 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001032 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001033{
1034 longobject *z;
1035 long shiftby;
1036 int newsize, wordshift, loshift, hishift, i, j;
1037 digit lomask, himask;
1038
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001039 if (a->ob_size < 0) {
1040 /* Right shifting negative numbers is harder */
1041 longobject *a1, *a2, *a3;
1042 a1 = (longobject *) long_invert(a);
1043 if (a1 == NULL) return NULL;
1044 a2 = (longobject *) long_rshift(a1, b);
1045 DECREF(a1);
1046 if (a2 == NULL) return NULL;
1047 a3 = (longobject *) long_invert(a2);
1048 DECREF(a2);
1049 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001050 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001051
1052 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001053 if (shiftby == -1L && err_occurred())
1054 return NULL;
1055 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001056 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001057 return NULL;
1058 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001059 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001060 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001061 if (newsize <= 0) {
1062 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001063 return (object *)z;
1064 }
1065 loshift = shiftby % SHIFT;
1066 hishift = SHIFT - loshift;
1067 lomask = ((digit)1 << hishift) - 1;
1068 himask = MASK ^ lomask;
1069 z = alloclongobject(newsize);
1070 if (z == NULL)
1071 return NULL;
1072 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001073 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001074 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1075 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1076 if (i+1 < newsize)
1077 z->ob_digit[i] |=
1078 (a->ob_digit[j+1] << hishift) & himask;
1079 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001080 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001081}
1082
1083static object *
1084long_lshift(a, b)
1085 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001086 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001087{
1088 longobject *z;
1089 long shiftby;
1090 int newsize, wordshift, loshift, hishift, i, j;
1091 digit lomask, himask;
1092
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001093 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001094 if (shiftby == -1L && err_occurred())
1095 return NULL;
1096 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001097 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001098 return NULL;
1099 }
1100 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001101 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001102 return NULL;
1103 }
1104 if (shiftby % SHIFT == 0) {
1105 wordshift = shiftby / SHIFT;
1106 loshift = 0;
1107 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001108 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001109 lomask = MASK;
1110 himask = 0;
1111 }
1112 else {
1113 wordshift = shiftby / SHIFT + 1;
1114 loshift = SHIFT - shiftby%SHIFT;
1115 hishift = shiftby % SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001116 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001117 lomask = ((digit)1 << hishift) - 1;
1118 himask = MASK ^ lomask;
1119 }
1120 z = alloclongobject(newsize);
1121 if (z == NULL)
1122 return NULL;
1123 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001124 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001125 for (i = 0; i < wordshift; i++)
1126 z->ob_digit[i] = 0;
1127 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1128 if (i > 0)
1129 z->ob_digit[i-1] |=
1130 (a->ob_digit[j] << hishift) & himask;
1131 z->ob_digit[i] =
1132 (a->ob_digit[j] >> loshift) & lomask;
1133 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001134 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001135}
1136
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001137
1138/* Bitwise and/xor/or operations */
1139
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001140#define MAX(x, y) ((x) < (y) ? (y) : (x))
1141#define MIN(x, y) ((x) > (y) ? (y) : (x))
1142
Guido van Rossume32e0141992-01-19 16:31:05 +00001143static object *long_bitwise PROTO((longobject *, int, longobject *));
1144static object *
1145long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001146 longobject *a;
1147 int op; /* '&', '|', '^' */
1148 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001149{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001150 digit maska, maskb; /* 0 or MASK */
1151 int negz;
1152 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001153 longobject *z;
1154 int i;
Guido van Rossum8b27d921992-03-27 17:27:05 +00001155 digit diga, digb;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001156 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001157
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001158 if (a->ob_size < 0) {
1159 a = (longobject *) long_invert(a);
1160 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001161 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001162 else {
1163 INCREF(a);
1164 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001165 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001166 if (b->ob_size < 0) {
1167 b = (longobject *) long_invert(b);
1168 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001169 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001170 else {
1171 INCREF(b);
1172 maskb = 0;
1173 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001174
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001175 size_a = a->ob_size;
1176 size_b = b->ob_size;
1177 size_z = MAX(size_a, size_b);
1178 z = alloclongobject(size_z);
1179 if (a == NULL || b == NULL || z == NULL) {
1180 XDECREF(a);
1181 XDECREF(b);
1182 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001183 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001184 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001185
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001186 negz = 0;
1187 switch (op) {
1188 case '^':
1189 if (maska != maskb) {
1190 maska ^= MASK;
1191 negz = -1;
1192 }
1193 break;
1194 case '&':
1195 if (maska && maskb) {
1196 op = '|';
1197 maska ^= MASK;
1198 maskb ^= MASK;
1199 negz = -1;
1200 }
1201 break;
1202 case '|':
1203 if (maska || maskb) {
1204 op = '&';
1205 maska ^= MASK;
1206 maskb ^= MASK;
1207 negz = -1;
1208 }
1209 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001210 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001211
1212 for (i = 0; i < size_z; ++i) {
1213 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1214 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1215 switch (op) {
1216 case '&': z->ob_digit[i] = diga & digb; break;
1217 case '|': z->ob_digit[i] = diga | digb; break;
1218 case '^': z->ob_digit[i] = diga ^ digb; break;
1219 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001220 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001221
1222 DECREF(a);
1223 DECREF(b);
1224 z = long_normalize(z);
1225 if (negz == 0)
1226 return (object *) z;
1227 v = long_invert(z);
1228 DECREF(z);
1229 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001230}
1231
Guido van Rossumc6913e71991-11-19 20:26:46 +00001232static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001233long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001234 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001235 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001236{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001237 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001238}
1239
1240static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001241long_xor(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001242 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001243 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001244{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001245 return long_bitwise(a, '^', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001246}
1247
1248static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001249long_or(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001250 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001251 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001252{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001253 return long_bitwise(a, '|', b);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001254}
1255
Guido van Rossume6eefc21992-08-14 12:06:52 +00001256int
1257long_coerce(pv, pw)
1258 object **pv;
1259 object **pw;
1260{
1261 if (is_intobject(*pw)) {
1262 *pw = newlongobject(getintvalue(*pw));
1263 INCREF(*pv);
1264 return 0;
1265 }
1266 return 1; /* Can't do it */
1267}
1268
Guido van Rossum8b27d921992-03-27 17:27:05 +00001269#define UF (object* (*) FPROTO((object *))) /* Unary function */
1270#define BF (object* (*) FPROTO((object *, object *))) /* Binary function */
1271#define IF (int (*) FPROTO((object *))) /* Int function */
1272
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001273static number_methods long_as_number = {
Guido van Rossum8b27d921992-03-27 17:27:05 +00001274 BF long_add, /*nb_add*/
1275 BF long_sub, /*nb_subtract*/
1276 BF long_mul, /*nb_multiply*/
1277 BF long_div, /*nb_divide*/
1278 BF long_mod, /*nb_remainder*/
1279 BF long_divmod, /*nb_divmod*/
1280 BF long_pow, /*nb_power*/
1281 UF long_neg, /*nb_negative*/
1282 UF long_pos, /*tp_positive*/
1283 UF long_abs, /*tp_absolute*/
1284 IF long_nonzero,/*tp_nonzero*/
1285 UF long_invert, /*nb_invert*/
1286 BF long_lshift, /*nb_lshift*/
1287 BF long_rshift, /*nb_rshift*/
1288 BF long_and, /*nb_and*/
1289 BF long_xor, /*nb_xor*/
1290 BF long_or, /*nb_or*/
Guido van Rossume6eefc21992-08-14 12:06:52 +00001291 (int (*) FPROTO((object **, object **)))
1292 long_coerce, /*nb_coerce*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001293};
1294
1295typeobject Longtype = {
1296 OB_HEAD_INIT(&Typetype)
1297 0,
1298 "long int",
1299 sizeof(longobject) - sizeof(digit),
1300 sizeof(digit),
1301 long_dealloc, /*tp_dealloc*/
1302 long_print, /*tp_print*/
1303 0, /*tp_getattr*/
1304 0, /*tp_setattr*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001305 (int (*) FPROTO((object *, object *)))
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001306 long_compare, /*tp_compare*/
1307 long_repr, /*tp_repr*/
1308 &long_as_number,/*tp_as_number*/
1309 0, /*tp_as_sequence*/
1310 0, /*tp_as_mapping*/
1311};