blob: 8c0b6c1c80b678a3402b0585756e0e3721f821bc [file] [log] [blame]
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001/***********************************************************
Guido van Rossum34679b71993-01-26 13:33:44 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumedcc38a1991-05-05 20:09:44 +00004
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 Rossum234f9421993-06-17 12:35:49 +0000264static object *
Guido van Rossume32e0141992-01-19 16:31:05 +0000265long_format(aa, base)
266 object *aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000267 int base;
268{
Guido van Rossume32e0141992-01-19 16:31:05 +0000269 register longobject *a = (longobject *)aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000270 stringobject *str;
271 int i;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000272 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000273 char *p;
274 int bits;
275 char sign = '\0';
Guido van Rossume32e0141992-01-19 16:31:05 +0000276
277 if (a == NULL || !is_longobject(a)) {
278 err_badcall();
279 return NULL;
280 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000281 assert(base >= 2 && base <= 36);
282
283 /* Compute a rough upper bound for the length of the string */
284 i = base;
285 bits = 0;
286 while (i > 1) {
287 ++bits;
288 i >>= 1;
289 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000290 i = 6 + (size_a*SHIFT + bits-1) / bits;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000291 str = (stringobject *) newsizedstringobject((char *)0, i);
292 if (str == NULL)
293 return NULL;
294 p = GETSTRINGVALUE(str) + i;
295 *p = '\0';
Guido van Rossumc6913e71991-11-19 20:26:46 +0000296 *--p = 'L';
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000297 if (a->ob_size < 0)
298 sign = '-';
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000299
300 INCREF(a);
301 do {
302 digit rem;
303 longobject *temp = divrem1(a, (digit)base, &rem);
304 if (temp == NULL) {
305 DECREF(a);
306 DECREF(str);
307 return NULL;
308 }
309 if (rem < 10)
310 rem += '0';
311 else
312 rem += 'A'-10;
313 assert(p > GETSTRINGVALUE(str));
314 *--p = rem;
315 DECREF(a);
316 a = temp;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000317 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000318 DECREF(a);
319 DECREF(str);
320 err_set(KeyboardInterrupt);
321 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000322 })
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000323 } while (ABS(a->ob_size) != 0);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000324 DECREF(a);
Guido van Rossum2c475421992-08-14 15:13:07 +0000325 if (base == 8) {
326 if (size_a != 0)
327 *--p = '0';
328 }
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000329 else if (base == 16) {
330 *--p = 'x';
331 *--p = '0';
332 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000333 else if (base != 10) {
334 *--p = '#';
335 *--p = '0' + base%10;
336 if (base > 10)
337 *--p = '0' + base/10;
338 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000339 if (sign)
340 *--p = sign;
341 if (p != GETSTRINGVALUE(str)) {
342 char *q = GETSTRINGVALUE(str);
343 assert(p > q);
344 do {
345 } while ((*q++ = *p++) != '\0');
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000346 q--;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000347 resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
348 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000349 return (object *)str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000350}
351
352/* Convert a string to a long int object, in a given base.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000353 Base zero implies a default depending on the number.
354 External linkage: used in compile.c for literals. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000355
356object *
357long_scan(str, base)
358 char *str;
359 int base;
360{
361 int sign = 1;
362 longobject *z;
363
364 assert(base == 0 || base >= 2 && base <= 36);
365 if (*str == '+')
366 ++str;
367 else if (*str == '-') {
368 ++str;
369 sign = -1;
370 }
371 if (base == 0) {
372 if (str[0] != '0')
373 base = 10;
374 else if (str[1] == 'x' || str[1] == 'X')
375 base = 16;
376 else
377 base = 8;
378 }
379 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
380 str += 2;
381 z = alloclongobject(0);
382 for ( ; z != NULL; ++str) {
383 int k = -1;
384 longobject *temp;
385
386 if (*str <= '9')
387 k = *str - '0';
388 else if (*str >= 'a')
389 k = *str - 'a' + 10;
390 else if (*str >= 'A')
391 k = *str - 'A' + 10;
392 if (k < 0 || k >= base)
393 break;
394 temp = muladd1(z, (digit)base, (digit)k);
395 DECREF(z);
396 z = temp;
397 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000398 if (sign < 0 && z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000399 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000400 return (object *) z;
401}
402
403static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
Guido van Rossumc6913e71991-11-19 20:26:46 +0000404static object *long_pos PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000405static long_divrem PROTO((longobject *, longobject *,
406 longobject **, longobject **));
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000407
408/* Long division with remainder, top-level routine */
409
Guido van Rossume32e0141992-01-19 16:31:05 +0000410static int
411long_divrem(a, b, pdiv, prem)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000412 longobject *a, *b;
Guido van Rossume32e0141992-01-19 16:31:05 +0000413 longobject **pdiv;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000414 longobject **prem;
415{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000416 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000417 longobject *z;
418
419 if (size_b == 0) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000420 err_setstr(ZeroDivisionError, "long division or modulo");
421 return -1;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000422 }
423 if (size_a < size_b ||
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000424 size_a == size_b &&
425 a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000426 /* |a| < |b|. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000427 *pdiv = alloclongobject(0);
428 INCREF(a);
429 *prem = (longobject *) a;
430 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000431 }
432 if (size_b == 1) {
433 digit rem = 0;
434 z = divrem1(a, b->ob_digit[0], &rem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000435 if (z == NULL)
436 return -1;
437 *prem = (longobject *) newlongobject((long)rem);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000438 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000439 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000440 z = x_divrem(a, b, prem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000441 if (z == NULL)
442 return -1;
443 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000444 /* Set the signs.
445 The quotient z has the sign of a*b;
446 the remainder r has the sign of a,
447 so a = b*z + r. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000448 if ((a->ob_size < 0) != (b->ob_size < 0))
449 z->ob_size = -(z->ob_size);
450 if (a->ob_size < 0 && (*prem)->ob_size != 0)
451 (*prem)->ob_size = -((*prem)->ob_size);
452 *pdiv = z;
453 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000454}
455
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000456/* Unsigned long division with remainder -- the algorithm */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000457
458static longobject *
459x_divrem(v1, w1, prem)
460 longobject *v1, *w1;
461 longobject **prem;
462{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000463 int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000464 digit d = (twodigits)BASE / (w1->ob_digit[size_w-1] + 1);
465 longobject *v = mul1(v1, d);
466 longobject *w = mul1(w1, d);
467 longobject *a;
468 int j, k;
469
470 if (v == NULL || w == NULL) {
471 XDECREF(v);
472 XDECREF(w);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000473 return NULL;
474 }
475
476 assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000477 assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000478 assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000479
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000480 size_v = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000481 a = alloclongobject(size_v - size_w + 1);
482
483 for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
484 digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
485 twodigits q;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000486 stwodigits carry = 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000487 int i;
488
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000489 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000490 DECREF(a);
491 a = NULL;
492 err_set(KeyboardInterrupt);
493 break;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000494 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000495 if (vj == w->ob_digit[size_w-1])
496 q = MASK;
497 else
498 q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
499 w->ob_digit[size_w-1];
500
501 while (w->ob_digit[size_w-2]*q >
502 ((
503 ((twodigits)vj << SHIFT)
504 + v->ob_digit[j-1]
505 - q*w->ob_digit[size_w-1]
506 ) << SHIFT)
507 + v->ob_digit[j-2])
508 --q;
509
510 for (i = 0; i < size_w && i+k < size_v; ++i) {
511 twodigits z = w->ob_digit[i] * q;
512 digit zz = z >> SHIFT;
513 carry += v->ob_digit[i+k] - z + ((twodigits)zz << SHIFT);
514 v->ob_digit[i+k] = carry & MASK;
515 carry = (carry >> SHIFT) - zz;
516 }
517
518 if (i+k < size_v) {
519 carry += v->ob_digit[i+k];
520 v->ob_digit[i+k] = 0;
521 }
522
523 if (carry == 0)
524 a->ob_digit[k] = q;
525 else {
526 assert(carry == -1);
527 a->ob_digit[k] = q-1;
528 carry = 0;
529 for (i = 0; i < size_w && i+k < size_v; ++i) {
530 carry += v->ob_digit[i+k] + w->ob_digit[i];
531 v->ob_digit[i+k] = carry & MASK;
532 carry >>= SHIFT;
533 }
534 }
535 } /* for j, k */
536
Guido van Rossume32e0141992-01-19 16:31:05 +0000537 if (a != NULL) {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000538 a = long_normalize(a);
Guido van Rossume32e0141992-01-19 16:31:05 +0000539 *prem = divrem1(v, d, &d);
540 /* d receives the (unused) remainder */
541 if (*prem == NULL) {
542 DECREF(a);
543 a = NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000544 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000545 }
546 DECREF(v);
547 DECREF(w);
548 return a;
549}
550
551/* Methods */
552
Guido van Rossume32e0141992-01-19 16:31:05 +0000553/* Forward */
Guido van Rossum8b27d921992-03-27 17:27:05 +0000554static void long_dealloc PROTO((object *));
555static int long_print PROTO((object *, FILE *, int));
556static object *long_repr PROTO((object *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000557static int long_compare PROTO((longobject *, longobject *));
Guido van Rossum9bfef441993-03-29 10:43:31 +0000558static long long_hash PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000559
560static object *long_add PROTO((longobject *, longobject *));
561static object *long_sub PROTO((longobject *, longobject *));
562static object *long_mul PROTO((longobject *, longobject *));
563static object *long_div PROTO((longobject *, longobject *));
564static object *long_mod PROTO((longobject *, longobject *));
565static object *long_divmod PROTO((longobject *, longobject *));
566static object *long_pow PROTO((longobject *, longobject *));
567static object *long_neg PROTO((longobject *));
568static object *long_pos PROTO((longobject *));
569static object *long_abs PROTO((longobject *));
570static int long_nonzero PROTO((longobject *));
571static object *long_invert PROTO((longobject *));
572static object *long_lshift PROTO((longobject *, longobject *));
573static object *long_rshift PROTO((longobject *, longobject *));
574static object *long_and PROTO((longobject *, longobject *));
575static object *long_xor PROTO((longobject *, longobject *));
576static object *long_or PROTO((longobject *, longobject *));
577
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000578static void
579long_dealloc(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000580 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000581{
582 DEL(v);
583}
584
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000585static object *
586long_repr(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000587 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000588{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000589 return long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000590}
591
592static int
593long_compare(a, b)
594 longobject *a, *b;
595{
596 int sign;
597
Guido van Rossumc6913e71991-11-19 20:26:46 +0000598 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000599 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000600 sign = 0;
601 else
602 sign = a->ob_size - b->ob_size;
603 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000604 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000605 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000606 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
607 ;
608 if (i < 0)
609 sign = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000610 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000611 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000612 if (a->ob_size < 0)
613 sign = -sign;
614 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000615 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000616 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000617}
618
Guido van Rossum9bfef441993-03-29 10:43:31 +0000619static long
620long_hash(v)
621 longobject *v;
622{
623 long x;
624 int i, sign;
625
626 /* This is designed so that Python ints and longs with the
627 same value hash to the same value, otherwise comparisons
628 of mapping keys will turn out weird */
629 i = v->ob_size;
630 sign = 1;
631 x = 0;
632 if (i < 0) {
633 sign = -1;
634 i = -(i);
635 }
636 while (--i >= 0) {
637 /* Force a 32-bit circular shift */
638 x = ((x << SHIFT) & ~MASK) | ((x >> (32-SHIFT)) & MASK);
639 x += v->ob_digit[i];
640 }
641 x = x * sign;
642 if (x == -1)
643 x = -2;
644 return x;
645}
646
647
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000648/* Add the absolute values of two long integers. */
649
650static longobject *x_add PROTO((longobject *, longobject *));
651static longobject *
652x_add(a, b)
653 longobject *a, *b;
654{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000655 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000656 longobject *z;
657 int i;
658 digit carry = 0;
659
660 /* Ensure a is the larger of the two: */
661 if (size_a < size_b) {
662 { longobject *temp = a; a = b; b = temp; }
663 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
664 }
665 z = alloclongobject(size_a+1);
666 if (z == NULL)
667 return NULL;
668 for (i = 0; i < size_b; ++i) {
669 carry += a->ob_digit[i] + b->ob_digit[i];
670 z->ob_digit[i] = carry & MASK;
671 /* The following assumes unsigned shifts don't
672 propagate the sign bit. */
673 carry >>= SHIFT;
674 }
675 for (; i < size_a; ++i) {
676 carry += a->ob_digit[i];
677 z->ob_digit[i] = carry & MASK;
678 carry >>= SHIFT;
679 }
680 z->ob_digit[i] = carry;
681 return long_normalize(z);
682}
683
684/* Subtract the absolute values of two integers. */
685
686static longobject *x_sub PROTO((longobject *, longobject *));
687static longobject *
688x_sub(a, b)
689 longobject *a, *b;
690{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000691 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000692 longobject *z;
693 int i;
694 int sign = 1;
695 digit borrow = 0;
696
697 /* Ensure a is the larger of the two: */
698 if (size_a < size_b) {
699 sign = -1;
700 { longobject *temp = a; a = b; b = temp; }
701 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
702 }
703 else if (size_a == size_b) {
704 /* Find highest digit where a and b differ: */
705 i = size_a;
706 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
707 ;
708 if (i < 0)
709 return alloclongobject(0);
710 if (a->ob_digit[i] < b->ob_digit[i]) {
711 sign = -1;
712 { longobject *temp = a; a = b; b = temp; }
713 }
714 size_a = size_b = i+1;
715 }
716 z = alloclongobject(size_a);
717 if (z == NULL)
718 return NULL;
719 for (i = 0; i < size_b; ++i) {
720 /* The following assumes unsigned arithmetic
721 works module 2**N for some N>SHIFT. */
722 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
723 z->ob_digit[i] = borrow & MASK;
724 borrow >>= SHIFT;
725 borrow &= 1; /* Keep only one sign bit */
726 }
727 for (; i < size_a; ++i) {
728 borrow = a->ob_digit[i] - borrow;
729 z->ob_digit[i] = borrow & MASK;
730 borrow >>= SHIFT;
731 }
732 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000733 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000734 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000735 return long_normalize(z);
736}
737
738static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000739long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000740 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000741 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000742{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000743 longobject *z;
744
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000745 if (a->ob_size < 0) {
746 if (b->ob_size < 0) {
747 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000748 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000749 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000750 }
751 else
752 z = x_sub(b, a);
753 }
754 else {
755 if (b->ob_size < 0)
756 z = x_sub(a, b);
757 else
758 z = x_add(a, b);
759 }
760 return (object *)z;
761}
762
763static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000764long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000765 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000766 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000767{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000768 longobject *z;
769
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000770 if (a->ob_size < 0) {
771 if (b->ob_size < 0)
772 z = x_sub(a, b);
773 else
774 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000775 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000776 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000777 }
778 else {
779 if (b->ob_size < 0)
780 z = x_add(a, b);
781 else
782 z = x_sub(a, b);
783 }
784 return (object *)z;
785}
786
787static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000788long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000789 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000790 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000791{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000792 int size_a;
793 int size_b;
794 longobject *z;
795 int i;
796
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000797 size_a = ABS(a->ob_size);
798 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000799 z = alloclongobject(size_a + size_b);
800 if (z == NULL)
801 return NULL;
802 for (i = 0; i < z->ob_size; ++i)
803 z->ob_digit[i] = 0;
804 for (i = 0; i < size_a; ++i) {
805 twodigits carry = 0;
806 twodigits f = a->ob_digit[i];
807 int j;
808
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000809 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000810 DECREF(z);
811 err_set(KeyboardInterrupt);
812 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000813 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000814 for (j = 0; j < size_b; ++j) {
815 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
816 z->ob_digit[i+j] = carry & MASK;
817 carry >>= SHIFT;
818 }
819 for (; carry != 0; ++j) {
820 assert(i+j < z->ob_size);
821 carry += z->ob_digit[i+j];
822 z->ob_digit[i+j] = carry & MASK;
823 carry >>= SHIFT;
824 }
825 }
826 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000827 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000828 if (b->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000829 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000830 return (object *) long_normalize(z);
831}
832
Guido van Rossume32e0141992-01-19 16:31:05 +0000833/* The / and % operators are now defined in terms of divmod().
834 The expression a mod b has the value a - b*floor(a/b).
835 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000836 |a| by |b|, with the sign of a. This is also expressed
837 as a - b*trunc(a/b), if trunc truncates towards zero.
838 Some examples:
839 a b a rem b a mod b
840 13 10 3 3
841 -13 10 -3 7
842 13 -10 3 -7
843 -13 -10 -3 -3
844 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000845 have different signs. We then subtract one from the 'div'
846 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000847
Guido van Rossume32e0141992-01-19 16:31:05 +0000848static int l_divmod PROTO((longobject *, longobject *,
849 longobject **, longobject **));
850static int
851l_divmod(v, w, pdiv, pmod)
852 longobject *v;
853 longobject *w;
854 longobject **pdiv;
855 longobject **pmod;
856{
857 longobject *div, *mod;
858
859 if (long_divrem(v, w, &div, &mod) < 0)
860 return -1;
861 if (mod->ob_size < 0 && w->ob_size > 0 ||
862 mod->ob_size > 0 && w->ob_size < 0) {
863 longobject *temp;
864 longobject *one;
865 temp = (longobject *) long_add(mod, w);
866 DECREF(mod);
867 mod = temp;
868 if (mod == NULL) {
869 DECREF(div);
870 return -1;
871 }
872 one = (longobject *) newlongobject(1L);
873 if (one == NULL ||
874 (temp = (longobject *) long_sub(div, one)) == NULL) {
875 DECREF(mod);
876 DECREF(div);
Guido van Rossume5372401993-03-16 12:15:04 +0000877 XDECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000878 return -1;
879 }
Guido van Rossume5372401993-03-16 12:15:04 +0000880 DECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000881 DECREF(div);
882 div = temp;
883 }
884 *pdiv = div;
885 *pmod = mod;
886 return 0;
887}
888
889static object *
890long_div(v, w)
891 longobject *v;
892 longobject *w;
893{
894 longobject *div, *mod;
895 if (l_divmod(v, w, &div, &mod) < 0)
896 return NULL;
897 DECREF(mod);
898 return (object *)div;
899}
900
901static object *
902long_mod(v, w)
903 longobject *v;
904 longobject *w;
905{
906 longobject *div, *mod;
907 if (l_divmod(v, w, &div, &mod) < 0)
908 return NULL;
909 DECREF(div);
910 return (object *)mod;
911}
912
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000913static object *
914long_divmod(v, w)
915 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000916 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000917{
918 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000919 longobject *div, *mod;
920 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000921 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000922 z = newtupleobject(2);
923 if (z != NULL) {
924 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000925 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000926 }
927 else {
928 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000929 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000930 }
931 return z;
932}
933
934static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000935long_pow(a, b)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000936 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000937 longobject *b;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000938{
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000939 longobject *z;
940 int size_b, i;
941
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000942 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000943 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000944 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000945 return NULL;
946 }
947
948 z = (longobject *)newlongobject(1L);
949
950 INCREF(a);
951 for (i = 0; i < size_b; ++i) {
952 digit bi = b->ob_digit[i];
953 int j;
954
955 for (j = 0; j < SHIFT; ++j) {
956 longobject *temp;
957
958 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000959 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000960 DECREF(z);
961 z = temp;
962 if (z == NULL)
963 break;
964 }
965 bi >>= 1;
966 if (bi == 0 && i+1 == size_b)
967 break;
Guido van Rossume32e0141992-01-19 16:31:05 +0000968 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000969 DECREF(a);
970 a = temp;
971 if (a == NULL) {
972 DECREF(z);
973 z = NULL;
974 break;
975 }
976 }
977 if (a == NULL)
978 break;
979 }
980 XDECREF(a);
981 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000982}
983
984static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +0000985long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000986 longobject *v;
987{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000988 /* Implement ~x as -(x+1) */
989 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +0000990 longobject *w;
991 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000992 if (w == NULL)
993 return NULL;
994 x = (longobject *) long_add(v, w);
995 DECREF(w);
996 if (x == NULL)
997 return NULL;
998 if (x->ob_size != 0)
999 x->ob_size = -(x->ob_size);
1000 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001001}
1002
1003static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001004long_pos(v)
1005 longobject *v;
1006{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001007 INCREF(v);
1008 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001009}
1010
1011static object *
1012long_neg(v)
1013 longobject *v;
1014{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001015 longobject *z;
1016 int i, n;
1017 n = ABS(v->ob_size);
1018 if (n == 0) {
1019 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001020 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001021 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001022 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001023 z = alloclongobject(ABS(n));
1024 if (z == NULL)
1025 return NULL;
1026 for (i = 0; i < n; i++)
1027 z->ob_digit[i] = v->ob_digit[i];
1028 z->ob_size = -(v->ob_size);
1029 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001030}
1031
1032static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001033long_abs(v)
1034 longobject *v;
1035{
1036 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001037 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001038 else {
1039 INCREF(v);
1040 return (object *)v;
1041 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001042}
1043
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001044static int
1045long_nonzero(v)
1046 longobject *v;
1047{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001048 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001049}
1050
1051static object *
1052long_rshift(a, b)
1053 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001054 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001055{
1056 longobject *z;
1057 long shiftby;
1058 int newsize, wordshift, loshift, hishift, i, j;
1059 digit lomask, himask;
1060
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001061 if (a->ob_size < 0) {
1062 /* Right shifting negative numbers is harder */
1063 longobject *a1, *a2, *a3;
1064 a1 = (longobject *) long_invert(a);
1065 if (a1 == NULL) return NULL;
1066 a2 = (longobject *) long_rshift(a1, b);
1067 DECREF(a1);
1068 if (a2 == NULL) return NULL;
1069 a3 = (longobject *) long_invert(a2);
1070 DECREF(a2);
1071 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001072 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001073
1074 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001075 if (shiftby == -1L && err_occurred())
1076 return NULL;
1077 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001078 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001079 return NULL;
1080 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001081 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001082 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001083 if (newsize <= 0) {
1084 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001085 return (object *)z;
1086 }
1087 loshift = shiftby % SHIFT;
1088 hishift = SHIFT - loshift;
1089 lomask = ((digit)1 << hishift) - 1;
1090 himask = MASK ^ lomask;
1091 z = alloclongobject(newsize);
1092 if (z == NULL)
1093 return NULL;
1094 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001095 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001096 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1097 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1098 if (i+1 < newsize)
1099 z->ob_digit[i] |=
1100 (a->ob_digit[j+1] << hishift) & himask;
1101 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001102 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001103}
1104
1105static object *
1106long_lshift(a, b)
1107 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001108 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001109{
1110 longobject *z;
1111 long shiftby;
1112 int newsize, wordshift, loshift, hishift, i, j;
1113 digit lomask, himask;
1114
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001115 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001116 if (shiftby == -1L && err_occurred())
1117 return NULL;
1118 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001119 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001120 return NULL;
1121 }
1122 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001123 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001124 return NULL;
1125 }
1126 if (shiftby % SHIFT == 0) {
1127 wordshift = shiftby / SHIFT;
1128 loshift = 0;
1129 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001130 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001131 lomask = MASK;
1132 himask = 0;
1133 }
1134 else {
1135 wordshift = shiftby / SHIFT + 1;
1136 loshift = SHIFT - shiftby%SHIFT;
1137 hishift = shiftby % SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001138 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001139 lomask = ((digit)1 << hishift) - 1;
1140 himask = MASK ^ lomask;
1141 }
1142 z = alloclongobject(newsize);
1143 if (z == NULL)
1144 return NULL;
1145 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001146 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001147 for (i = 0; i < wordshift; i++)
1148 z->ob_digit[i] = 0;
1149 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1150 if (i > 0)
1151 z->ob_digit[i-1] |=
1152 (a->ob_digit[j] << hishift) & himask;
1153 z->ob_digit[i] =
1154 (a->ob_digit[j] >> loshift) & lomask;
1155 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001156 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001157}
1158
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001159
1160/* Bitwise and/xor/or operations */
1161
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001162#define MAX(x, y) ((x) < (y) ? (y) : (x))
1163#define MIN(x, y) ((x) > (y) ? (y) : (x))
1164
Guido van Rossume32e0141992-01-19 16:31:05 +00001165static object *long_bitwise PROTO((longobject *, int, longobject *));
1166static object *
1167long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001168 longobject *a;
1169 int op; /* '&', '|', '^' */
1170 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001171{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001172 digit maska, maskb; /* 0 or MASK */
1173 int negz;
1174 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001175 longobject *z;
1176 int i;
Guido van Rossum8b27d921992-03-27 17:27:05 +00001177 digit diga, digb;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001178 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001179
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001180 if (a->ob_size < 0) {
1181 a = (longobject *) long_invert(a);
1182 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001183 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001184 else {
1185 INCREF(a);
1186 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001187 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001188 if (b->ob_size < 0) {
1189 b = (longobject *) long_invert(b);
1190 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001191 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001192 else {
1193 INCREF(b);
1194 maskb = 0;
1195 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001196
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001197 size_a = a->ob_size;
1198 size_b = b->ob_size;
1199 size_z = MAX(size_a, size_b);
1200 z = alloclongobject(size_z);
1201 if (a == NULL || b == NULL || z == NULL) {
1202 XDECREF(a);
1203 XDECREF(b);
1204 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001205 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001206 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001207
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001208 negz = 0;
1209 switch (op) {
1210 case '^':
1211 if (maska != maskb) {
1212 maska ^= MASK;
1213 negz = -1;
1214 }
1215 break;
1216 case '&':
1217 if (maska && maskb) {
1218 op = '|';
1219 maska ^= MASK;
1220 maskb ^= MASK;
1221 negz = -1;
1222 }
1223 break;
1224 case '|':
1225 if (maska || maskb) {
1226 op = '&';
1227 maska ^= MASK;
1228 maskb ^= MASK;
1229 negz = -1;
1230 }
1231 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001232 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001233
1234 for (i = 0; i < size_z; ++i) {
1235 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1236 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1237 switch (op) {
1238 case '&': z->ob_digit[i] = diga & digb; break;
1239 case '|': z->ob_digit[i] = diga | digb; break;
1240 case '^': z->ob_digit[i] = diga ^ digb; break;
1241 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001242 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001243
1244 DECREF(a);
1245 DECREF(b);
1246 z = long_normalize(z);
1247 if (negz == 0)
1248 return (object *) z;
1249 v = long_invert(z);
1250 DECREF(z);
1251 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001252}
1253
Guido van Rossumc6913e71991-11-19 20:26:46 +00001254static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001255long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001256 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001257 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001258{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001259 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001260}
1261
1262static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001263long_xor(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001264 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001265 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001266{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001267 return long_bitwise(a, '^', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001268}
1269
1270static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001271long_or(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001272 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001273 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001274{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001275 return long_bitwise(a, '|', b);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001276}
1277
Guido van Rossum234f9421993-06-17 12:35:49 +00001278static int
Guido van Rossume6eefc21992-08-14 12:06:52 +00001279long_coerce(pv, pw)
1280 object **pv;
1281 object **pw;
1282{
1283 if (is_intobject(*pw)) {
1284 *pw = newlongobject(getintvalue(*pw));
1285 INCREF(*pv);
1286 return 0;
1287 }
1288 return 1; /* Can't do it */
1289}
1290
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001291static object *
1292long_int(v)
1293 object *v;
1294{
1295 long x;
1296 x = getlongvalue(v);
1297 if (err_occurred())
1298 return NULL;
1299 return newintobject(x);
1300}
1301
1302static object *
1303long_long(v)
1304 object *v;
1305{
1306 INCREF(v);
1307 return v;
1308}
1309
1310static object *
1311long_float(v)
1312 object *v;
1313{
1314 return newfloatobject(dgetlongvalue(v));
1315}
1316
1317static object *
1318long_oct(v)
1319 object *v;
1320{
1321 return long_format(v, 8);
1322}
1323
1324static object *
1325long_hex(v)
1326 object *v;
1327{
1328 return long_format(v, 16);
1329}
1330
1331
Guido van Rossum8b27d921992-03-27 17:27:05 +00001332#define UF (object* (*) FPROTO((object *))) /* Unary function */
1333#define BF (object* (*) FPROTO((object *, object *))) /* Binary function */
1334#define IF (int (*) FPROTO((object *))) /* Int function */
1335
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001336static number_methods long_as_number = {
Guido van Rossum8b27d921992-03-27 17:27:05 +00001337 BF long_add, /*nb_add*/
1338 BF long_sub, /*nb_subtract*/
1339 BF long_mul, /*nb_multiply*/
1340 BF long_div, /*nb_divide*/
1341 BF long_mod, /*nb_remainder*/
1342 BF long_divmod, /*nb_divmod*/
1343 BF long_pow, /*nb_power*/
1344 UF long_neg, /*nb_negative*/
1345 UF long_pos, /*tp_positive*/
1346 UF long_abs, /*tp_absolute*/
1347 IF long_nonzero,/*tp_nonzero*/
1348 UF long_invert, /*nb_invert*/
1349 BF long_lshift, /*nb_lshift*/
1350 BF long_rshift, /*nb_rshift*/
1351 BF long_and, /*nb_and*/
1352 BF long_xor, /*nb_xor*/
1353 BF long_or, /*nb_or*/
Guido van Rossume6eefc21992-08-14 12:06:52 +00001354 (int (*) FPROTO((object **, object **)))
1355 long_coerce, /*nb_coerce*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001356 UF long_int, /*nb_int*/
1357 UF long_long, /*nb_long*/
1358 UF long_float, /*nb_float*/
1359 UF long_oct, /*nb_oct*/
1360 UF long_hex, /*nb_hex*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001361};
1362
1363typeobject Longtype = {
1364 OB_HEAD_INIT(&Typetype)
1365 0,
1366 "long int",
1367 sizeof(longobject) - sizeof(digit),
1368 sizeof(digit),
1369 long_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001370 0, /*tp_print*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001371 0, /*tp_getattr*/
1372 0, /*tp_setattr*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001373 (int (*) FPROTO((object *, object *)))
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001374 long_compare, /*tp_compare*/
1375 long_repr, /*tp_repr*/
1376 &long_as_number,/*tp_as_number*/
1377 0, /*tp_as_sequence*/
1378 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +00001379 (long (*) FPROTO((object *)))
1380 long_hash, /*tp_hash*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001381};