blob: 3e12639d7b1c02e29f803517f3beb32aa1d36f5d [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 *));
Guido van Rossumb73cc041993-11-01 16:28:59 +000042static object *long_format PROTO((object *aa, int base));
Guido van Rossume32e0141992-01-19 16:31:05 +000043
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000044static int ticker; /* XXX Could be shared with ceval? */
45
46#define INTRCHECK(block) \
47 if (--ticker < 0) { \
48 ticker = 100; \
49 if (intrcheck()) { block; } \
50 }
51
Guido van Rossumedcc38a1991-05-05 20:09:44 +000052/* Normalize (remove leading zeros from) a long int object.
53 Doesn't attempt to free the storage--in most cases, due to the nature
54 of the algorithms used, this could save at most be one word anyway. */
55
Guido van Rossum4c260ff1992-01-14 18:36:43 +000056static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +000057long_normalize(v)
58 register longobject *v;
59{
Guido van Rossum4c260ff1992-01-14 18:36:43 +000060 int j = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +000061 register int i = j;
62
63 while (i > 0 && v->ob_digit[i-1] == 0)
64 --i;
65 if (i != j)
Guido van Rossum4c260ff1992-01-14 18:36:43 +000066 v->ob_size = (v->ob_size < 0) ? -(i) : i;
Guido van Rossumedcc38a1991-05-05 20:09:44 +000067 return v;
68}
69
70/* Allocate a new long int object with size digits.
71 Return NULL and set exception if we run out of memory. */
72
73longobject *
74alloclongobject(size)
75 int size;
76{
77 return NEWVAROBJ(longobject, &Longtype, size);
78}
79
80/* Create a new long int object from a C long int */
81
82object *
83newlongobject(ival)
84 long ival;
85{
86 /* Assume a C long fits in at most 3 'digits' */
87 longobject *v = alloclongobject(3);
88 if (v != NULL) {
89 if (ival < 0) {
90 ival = -ival;
Guido van Rossum4c260ff1992-01-14 18:36:43 +000091 v->ob_size = -(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +000092 }
93 v->ob_digit[0] = ival & MASK;
94 v->ob_digit[1] = (ival >> SHIFT) & MASK;
95 v->ob_digit[2] = (ival >> (2*SHIFT)) & MASK;
96 v = long_normalize(v);
97 }
98 return (object *)v;
99}
100
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000101/* Create a new long int object from a C double */
102
103object *
104dnewlongobject(dval)
105 double dval;
106{
107 longobject *v;
108 double frac;
109 int i, ndig, expo, neg;
110 neg = 0;
111 if (dval < 0.0) {
112 neg = 1;
113 dval = -dval;
114 }
115 frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
116 if (expo <= 0)
117 return newlongobject(0L);
118 ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
119 v = alloclongobject(ndig);
120 if (v == NULL)
121 return NULL;
122 frac = ldexp(frac, (expo-1) % SHIFT + 1);
123 for (i = ndig; --i >= 0; ) {
124 long bits = (long)frac;
125 v->ob_digit[i] = bits;
126 frac = frac - (double)bits;
127 frac = ldexp(frac, SHIFT);
128 }
129 if (neg)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000130 v->ob_size = -(v->ob_size);
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000131 return (object *)v;
132}
133
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000134/* Get a C long int from a long int object.
135 Returns -1 and sets an error condition if overflow occurs. */
136
137long
138getlongvalue(vv)
139 object *vv;
140{
141 register longobject *v;
142 long x, prev;
143 int i, sign;
144
145 if (vv == NULL || !is_longobject(vv)) {
146 err_badcall();
147 return -1;
148 }
149 v = (longobject *)vv;
150 i = v->ob_size;
151 sign = 1;
152 x = 0;
153 if (i < 0) {
154 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000155 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000156 }
157 while (--i >= 0) {
158 prev = x;
159 x = (x << SHIFT) + v->ob_digit[i];
160 if ((x >> SHIFT) != prev) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000161 err_setstr(ValueError,
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000162 "long int too long to convert");
163 return -1;
164 }
165 }
166 return x * sign;
167}
168
169/* Get a C double from a long int object. No overflow check. */
170
171double
172dgetlongvalue(vv)
173 object *vv;
174{
175 register longobject *v;
176 double x;
177 double multiplier = (double) (1L << SHIFT);
178 int i, sign;
179
180 if (vv == NULL || !is_longobject(vv)) {
181 err_badcall();
182 return -1;
183 }
184 v = (longobject *)vv;
185 i = v->ob_size;
186 sign = 1;
187 x = 0.0;
188 if (i < 0) {
189 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000190 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000191 }
192 while (--i >= 0) {
193 x = x*multiplier + v->ob_digit[i];
194 }
195 return x * sign;
196}
197
198/* Multiply by a single digit, ignoring the sign. */
199
Guido van Rossume32e0141992-01-19 16:31:05 +0000200static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000201mul1(a, n)
202 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000203 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000204{
205 return muladd1(a, n, (digit)0);
206}
207
208/* Multiply by a single digit and add a single digit, ignoring the sign. */
209
Guido van Rossume32e0141992-01-19 16:31:05 +0000210static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000211muladd1(a, n, extra)
212 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000213 wdigit n;
214 wdigit extra;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000215{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000216 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000217 longobject *z = alloclongobject(size_a+1);
218 twodigits carry = extra;
219 int i;
220
221 if (z == NULL)
222 return NULL;
223 for (i = 0; i < size_a; ++i) {
224 carry += (twodigits)a->ob_digit[i] * n;
225 z->ob_digit[i] = carry & MASK;
226 carry >>= SHIFT;
227 }
228 z->ob_digit[i] = carry;
229 return long_normalize(z);
230}
231
232/* Divide a long integer by a digit, returning both the quotient
233 (as function result) and the remainder (through *prem).
234 The sign of a is ignored; n should not be zero. */
235
Guido van Rossume32e0141992-01-19 16:31:05 +0000236static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000237divrem1(a, n, prem)
238 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000239 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000240 digit *prem;
241{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000242 int size = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000243 longobject *z;
244 int i;
245 twodigits rem = 0;
246
247 assert(n > 0 && n <= MASK);
248 z = alloclongobject(size);
249 if (z == NULL)
250 return NULL;
251 for (i = size; --i >= 0; ) {
252 rem = (rem << SHIFT) + a->ob_digit[i];
253 z->ob_digit[i] = rem/n;
254 rem %= n;
255 }
256 *prem = rem;
257 return long_normalize(z);
258}
259
260/* Convert a long int object to a string, using a given conversion base.
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000261 Return a string object.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000262 If base is 8 or 16, add the proper prefix '0' or '0x'.
263 External linkage: used in bltinmodule.c by hex() and oct(). */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000264
Guido van Rossum234f9421993-06-17 12:35:49 +0000265static object *
Guido van Rossume32e0141992-01-19 16:31:05 +0000266long_format(aa, base)
267 object *aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000268 int base;
269{
Guido van Rossume32e0141992-01-19 16:31:05 +0000270 register longobject *a = (longobject *)aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000271 stringobject *str;
272 int i;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000273 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000274 char *p;
275 int bits;
276 char sign = '\0';
Guido van Rossume32e0141992-01-19 16:31:05 +0000277
278 if (a == NULL || !is_longobject(a)) {
279 err_badcall();
280 return NULL;
281 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000282 assert(base >= 2 && base <= 36);
283
284 /* Compute a rough upper bound for the length of the string */
285 i = base;
286 bits = 0;
287 while (i > 1) {
288 ++bits;
289 i >>= 1;
290 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000291 i = 6 + (size_a*SHIFT + bits-1) / bits;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000292 str = (stringobject *) newsizedstringobject((char *)0, i);
293 if (str == NULL)
294 return NULL;
295 p = GETSTRINGVALUE(str) + i;
296 *p = '\0';
Guido van Rossumc6913e71991-11-19 20:26:46 +0000297 *--p = 'L';
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000298 if (a->ob_size < 0)
299 sign = '-';
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000300
301 INCREF(a);
302 do {
303 digit rem;
304 longobject *temp = divrem1(a, (digit)base, &rem);
305 if (temp == NULL) {
306 DECREF(a);
307 DECREF(str);
308 return NULL;
309 }
310 if (rem < 10)
311 rem += '0';
312 else
313 rem += 'A'-10;
314 assert(p > GETSTRINGVALUE(str));
315 *--p = rem;
316 DECREF(a);
317 a = temp;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000318 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000319 DECREF(a);
320 DECREF(str);
321 err_set(KeyboardInterrupt);
322 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000323 })
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000324 } while (ABS(a->ob_size) != 0);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000325 DECREF(a);
Guido van Rossum2c475421992-08-14 15:13:07 +0000326 if (base == 8) {
327 if (size_a != 0)
328 *--p = '0';
329 }
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000330 else if (base == 16) {
331 *--p = 'x';
332 *--p = '0';
333 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000334 else if (base != 10) {
335 *--p = '#';
336 *--p = '0' + base%10;
337 if (base > 10)
338 *--p = '0' + base/10;
339 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000340 if (sign)
341 *--p = sign;
342 if (p != GETSTRINGVALUE(str)) {
343 char *q = GETSTRINGVALUE(str);
344 assert(p > q);
345 do {
346 } while ((*q++ = *p++) != '\0');
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000347 q--;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000348 resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
349 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000350 return (object *)str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000351}
352
353/* Convert a string to a long int object, in a given base.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000354 Base zero implies a default depending on the number.
355 External linkage: used in compile.c for literals. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000356
357object *
358long_scan(str, base)
359 char *str;
360 int base;
361{
362 int sign = 1;
363 longobject *z;
364
365 assert(base == 0 || base >= 2 && base <= 36);
366 if (*str == '+')
367 ++str;
368 else if (*str == '-') {
369 ++str;
370 sign = -1;
371 }
372 if (base == 0) {
373 if (str[0] != '0')
374 base = 10;
375 else if (str[1] == 'x' || str[1] == 'X')
376 base = 16;
377 else
378 base = 8;
379 }
380 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
381 str += 2;
382 z = alloclongobject(0);
383 for ( ; z != NULL; ++str) {
384 int k = -1;
385 longobject *temp;
386
387 if (*str <= '9')
388 k = *str - '0';
389 else if (*str >= 'a')
390 k = *str - 'a' + 10;
391 else if (*str >= 'A')
392 k = *str - 'A' + 10;
393 if (k < 0 || k >= base)
394 break;
395 temp = muladd1(z, (digit)base, (digit)k);
396 DECREF(z);
397 z = temp;
398 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000399 if (sign < 0 && z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000400 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000401 return (object *) z;
402}
403
404static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
Guido van Rossumc6913e71991-11-19 20:26:46 +0000405static object *long_pos PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000406static long_divrem PROTO((longobject *, longobject *,
407 longobject **, longobject **));
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000408
409/* Long division with remainder, top-level routine */
410
Guido van Rossume32e0141992-01-19 16:31:05 +0000411static int
412long_divrem(a, b, pdiv, prem)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000413 longobject *a, *b;
Guido van Rossume32e0141992-01-19 16:31:05 +0000414 longobject **pdiv;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000415 longobject **prem;
416{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000417 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000418 longobject *z;
419
420 if (size_b == 0) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000421 err_setstr(ZeroDivisionError, "long division or modulo");
422 return -1;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000423 }
424 if (size_a < size_b ||
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000425 size_a == size_b &&
426 a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000427 /* |a| < |b|. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000428 *pdiv = alloclongobject(0);
429 INCREF(a);
430 *prem = (longobject *) a;
431 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000432 }
433 if (size_b == 1) {
434 digit rem = 0;
435 z = divrem1(a, b->ob_digit[0], &rem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000436 if (z == NULL)
437 return -1;
438 *prem = (longobject *) newlongobject((long)rem);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000439 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000440 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000441 z = x_divrem(a, b, prem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000442 if (z == NULL)
443 return -1;
444 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000445 /* Set the signs.
446 The quotient z has the sign of a*b;
447 the remainder r has the sign of a,
448 so a = b*z + r. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000449 if ((a->ob_size < 0) != (b->ob_size < 0))
450 z->ob_size = -(z->ob_size);
451 if (a->ob_size < 0 && (*prem)->ob_size != 0)
452 (*prem)->ob_size = -((*prem)->ob_size);
453 *pdiv = z;
454 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000455}
456
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000457/* Unsigned long division with remainder -- the algorithm */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000458
459static longobject *
460x_divrem(v1, w1, prem)
461 longobject *v1, *w1;
462 longobject **prem;
463{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000464 int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000465 digit d = (twodigits)BASE / (w1->ob_digit[size_w-1] + 1);
466 longobject *v = mul1(v1, d);
467 longobject *w = mul1(w1, d);
468 longobject *a;
469 int j, k;
470
471 if (v == NULL || w == NULL) {
472 XDECREF(v);
473 XDECREF(w);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000474 return NULL;
475 }
476
477 assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000478 assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000479 assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000480
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000481 size_v = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000482 a = alloclongobject(size_v - size_w + 1);
483
484 for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
485 digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
486 twodigits q;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000487 stwodigits carry = 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000488 int i;
489
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000490 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000491 DECREF(a);
492 a = NULL;
493 err_set(KeyboardInterrupt);
494 break;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000495 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000496 if (vj == w->ob_digit[size_w-1])
497 q = MASK;
498 else
499 q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
500 w->ob_digit[size_w-1];
501
502 while (w->ob_digit[size_w-2]*q >
503 ((
504 ((twodigits)vj << SHIFT)
505 + v->ob_digit[j-1]
506 - q*w->ob_digit[size_w-1]
507 ) << SHIFT)
508 + v->ob_digit[j-2])
509 --q;
510
511 for (i = 0; i < size_w && i+k < size_v; ++i) {
512 twodigits z = w->ob_digit[i] * q;
513 digit zz = z >> SHIFT;
514 carry += v->ob_digit[i+k] - z + ((twodigits)zz << SHIFT);
515 v->ob_digit[i+k] = carry & MASK;
516 carry = (carry >> SHIFT) - zz;
517 }
518
519 if (i+k < size_v) {
520 carry += v->ob_digit[i+k];
521 v->ob_digit[i+k] = 0;
522 }
523
524 if (carry == 0)
525 a->ob_digit[k] = q;
526 else {
527 assert(carry == -1);
528 a->ob_digit[k] = q-1;
529 carry = 0;
530 for (i = 0; i < size_w && i+k < size_v; ++i) {
531 carry += v->ob_digit[i+k] + w->ob_digit[i];
532 v->ob_digit[i+k] = carry & MASK;
533 carry >>= SHIFT;
534 }
535 }
536 } /* for j, k */
537
Guido van Rossume32e0141992-01-19 16:31:05 +0000538 if (a != NULL) {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000539 a = long_normalize(a);
Guido van Rossume32e0141992-01-19 16:31:05 +0000540 *prem = divrem1(v, d, &d);
541 /* d receives the (unused) remainder */
542 if (*prem == NULL) {
543 DECREF(a);
544 a = NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000545 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000546 }
547 DECREF(v);
548 DECREF(w);
549 return a;
550}
551
552/* Methods */
553
Guido van Rossume32e0141992-01-19 16:31:05 +0000554/* Forward */
Guido van Rossum8b27d921992-03-27 17:27:05 +0000555static void long_dealloc PROTO((object *));
556static int long_print PROTO((object *, FILE *, int));
557static object *long_repr PROTO((object *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000558static int long_compare PROTO((longobject *, longobject *));
Guido van Rossum9bfef441993-03-29 10:43:31 +0000559static long long_hash PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000560
561static object *long_add PROTO((longobject *, longobject *));
562static object *long_sub PROTO((longobject *, longobject *));
563static object *long_mul PROTO((longobject *, longobject *));
564static object *long_div PROTO((longobject *, longobject *));
565static object *long_mod PROTO((longobject *, longobject *));
566static object *long_divmod PROTO((longobject *, longobject *));
567static object *long_pow PROTO((longobject *, longobject *));
568static object *long_neg PROTO((longobject *));
569static object *long_pos PROTO((longobject *));
570static object *long_abs PROTO((longobject *));
571static int long_nonzero PROTO((longobject *));
572static object *long_invert PROTO((longobject *));
573static object *long_lshift PROTO((longobject *, longobject *));
574static object *long_rshift PROTO((longobject *, longobject *));
575static object *long_and PROTO((longobject *, longobject *));
576static object *long_xor PROTO((longobject *, longobject *));
577static object *long_or PROTO((longobject *, longobject *));
578
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000579static void
580long_dealloc(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000581 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000582{
583 DEL(v);
584}
585
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000586static object *
587long_repr(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000588 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000589{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000590 return long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000591}
592
593static int
594long_compare(a, b)
595 longobject *a, *b;
596{
597 int sign;
598
Guido van Rossumc6913e71991-11-19 20:26:46 +0000599 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000600 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000601 sign = 0;
602 else
603 sign = a->ob_size - b->ob_size;
604 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000605 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000606 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000607 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
608 ;
609 if (i < 0)
610 sign = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000611 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000612 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000613 if (a->ob_size < 0)
614 sign = -sign;
615 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000616 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000617 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000618}
619
Guido van Rossum9bfef441993-03-29 10:43:31 +0000620static long
621long_hash(v)
622 longobject *v;
623{
624 long x;
625 int i, sign;
626
627 /* This is designed so that Python ints and longs with the
628 same value hash to the same value, otherwise comparisons
629 of mapping keys will turn out weird */
630 i = v->ob_size;
631 sign = 1;
632 x = 0;
633 if (i < 0) {
634 sign = -1;
635 i = -(i);
636 }
637 while (--i >= 0) {
638 /* Force a 32-bit circular shift */
639 x = ((x << SHIFT) & ~MASK) | ((x >> (32-SHIFT)) & MASK);
640 x += v->ob_digit[i];
641 }
642 x = x * sign;
643 if (x == -1)
644 x = -2;
645 return x;
646}
647
648
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000649/* Add the absolute values of two long integers. */
650
651static longobject *x_add PROTO((longobject *, longobject *));
652static longobject *
653x_add(a, b)
654 longobject *a, *b;
655{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000656 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000657 longobject *z;
658 int i;
659 digit carry = 0;
660
661 /* Ensure a is the larger of the two: */
662 if (size_a < size_b) {
663 { longobject *temp = a; a = b; b = temp; }
664 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
665 }
666 z = alloclongobject(size_a+1);
667 if (z == NULL)
668 return NULL;
669 for (i = 0; i < size_b; ++i) {
670 carry += a->ob_digit[i] + b->ob_digit[i];
671 z->ob_digit[i] = carry & MASK;
672 /* The following assumes unsigned shifts don't
673 propagate the sign bit. */
674 carry >>= SHIFT;
675 }
676 for (; i < size_a; ++i) {
677 carry += a->ob_digit[i];
678 z->ob_digit[i] = carry & MASK;
679 carry >>= SHIFT;
680 }
681 z->ob_digit[i] = carry;
682 return long_normalize(z);
683}
684
685/* Subtract the absolute values of two integers. */
686
687static longobject *x_sub PROTO((longobject *, longobject *));
688static longobject *
689x_sub(a, b)
690 longobject *a, *b;
691{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000692 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000693 longobject *z;
694 int i;
695 int sign = 1;
696 digit borrow = 0;
697
698 /* Ensure a is the larger of the two: */
699 if (size_a < size_b) {
700 sign = -1;
701 { longobject *temp = a; a = b; b = temp; }
702 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
703 }
704 else if (size_a == size_b) {
705 /* Find highest digit where a and b differ: */
706 i = size_a;
707 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
708 ;
709 if (i < 0)
710 return alloclongobject(0);
711 if (a->ob_digit[i] < b->ob_digit[i]) {
712 sign = -1;
713 { longobject *temp = a; a = b; b = temp; }
714 }
715 size_a = size_b = i+1;
716 }
717 z = alloclongobject(size_a);
718 if (z == NULL)
719 return NULL;
720 for (i = 0; i < size_b; ++i) {
721 /* The following assumes unsigned arithmetic
722 works module 2**N for some N>SHIFT. */
723 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
724 z->ob_digit[i] = borrow & MASK;
725 borrow >>= SHIFT;
726 borrow &= 1; /* Keep only one sign bit */
727 }
728 for (; i < size_a; ++i) {
729 borrow = a->ob_digit[i] - borrow;
730 z->ob_digit[i] = borrow & MASK;
731 borrow >>= SHIFT;
732 }
733 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000734 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000735 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000736 return long_normalize(z);
737}
738
739static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000740long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000741 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000742 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000743{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000744 longobject *z;
745
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000746 if (a->ob_size < 0) {
747 if (b->ob_size < 0) {
748 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000749 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000750 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000751 }
752 else
753 z = x_sub(b, a);
754 }
755 else {
756 if (b->ob_size < 0)
757 z = x_sub(a, b);
758 else
759 z = x_add(a, b);
760 }
761 return (object *)z;
762}
763
764static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000765long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000766 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000767 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000768{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000769 longobject *z;
770
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000771 if (a->ob_size < 0) {
772 if (b->ob_size < 0)
773 z = x_sub(a, b);
774 else
775 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000776 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000777 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000778 }
779 else {
780 if (b->ob_size < 0)
781 z = x_add(a, b);
782 else
783 z = x_sub(a, b);
784 }
785 return (object *)z;
786}
787
788static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000789long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000790 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000791 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000792{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000793 int size_a;
794 int size_b;
795 longobject *z;
796 int i;
797
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000798 size_a = ABS(a->ob_size);
799 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000800 z = alloclongobject(size_a + size_b);
801 if (z == NULL)
802 return NULL;
803 for (i = 0; i < z->ob_size; ++i)
804 z->ob_digit[i] = 0;
805 for (i = 0; i < size_a; ++i) {
806 twodigits carry = 0;
807 twodigits f = a->ob_digit[i];
808 int j;
809
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000810 INTRCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000811 DECREF(z);
812 err_set(KeyboardInterrupt);
813 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000814 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000815 for (j = 0; j < size_b; ++j) {
816 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
817 z->ob_digit[i+j] = carry & MASK;
818 carry >>= SHIFT;
819 }
820 for (; carry != 0; ++j) {
821 assert(i+j < z->ob_size);
822 carry += z->ob_digit[i+j];
823 z->ob_digit[i+j] = carry & MASK;
824 carry >>= SHIFT;
825 }
826 }
827 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000828 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000829 if (b->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000830 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000831 return (object *) long_normalize(z);
832}
833
Guido van Rossume32e0141992-01-19 16:31:05 +0000834/* The / and % operators are now defined in terms of divmod().
835 The expression a mod b has the value a - b*floor(a/b).
836 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000837 |a| by |b|, with the sign of a. This is also expressed
838 as a - b*trunc(a/b), if trunc truncates towards zero.
839 Some examples:
840 a b a rem b a mod b
841 13 10 3 3
842 -13 10 -3 7
843 13 -10 3 -7
844 -13 -10 -3 -3
845 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000846 have different signs. We then subtract one from the 'div'
847 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000848
Guido van Rossume32e0141992-01-19 16:31:05 +0000849static int l_divmod PROTO((longobject *, longobject *,
850 longobject **, longobject **));
851static int
852l_divmod(v, w, pdiv, pmod)
853 longobject *v;
854 longobject *w;
855 longobject **pdiv;
856 longobject **pmod;
857{
858 longobject *div, *mod;
859
860 if (long_divrem(v, w, &div, &mod) < 0)
861 return -1;
862 if (mod->ob_size < 0 && w->ob_size > 0 ||
863 mod->ob_size > 0 && w->ob_size < 0) {
864 longobject *temp;
865 longobject *one;
866 temp = (longobject *) long_add(mod, w);
867 DECREF(mod);
868 mod = temp;
869 if (mod == NULL) {
870 DECREF(div);
871 return -1;
872 }
873 one = (longobject *) newlongobject(1L);
874 if (one == NULL ||
875 (temp = (longobject *) long_sub(div, one)) == NULL) {
876 DECREF(mod);
877 DECREF(div);
Guido van Rossume5372401993-03-16 12:15:04 +0000878 XDECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000879 return -1;
880 }
Guido van Rossume5372401993-03-16 12:15:04 +0000881 DECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000882 DECREF(div);
883 div = temp;
884 }
885 *pdiv = div;
886 *pmod = mod;
887 return 0;
888}
889
890static object *
891long_div(v, w)
892 longobject *v;
893 longobject *w;
894{
895 longobject *div, *mod;
896 if (l_divmod(v, w, &div, &mod) < 0)
897 return NULL;
898 DECREF(mod);
899 return (object *)div;
900}
901
902static object *
903long_mod(v, w)
904 longobject *v;
905 longobject *w;
906{
907 longobject *div, *mod;
908 if (l_divmod(v, w, &div, &mod) < 0)
909 return NULL;
910 DECREF(div);
911 return (object *)mod;
912}
913
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000914static object *
915long_divmod(v, w)
916 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000917 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000918{
919 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000920 longobject *div, *mod;
921 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000922 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000923 z = newtupleobject(2);
924 if (z != NULL) {
925 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000926 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000927 }
928 else {
929 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000930 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000931 }
932 return z;
933}
934
935static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000936long_pow(a, b)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000937 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000938 longobject *b;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000939{
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000940 longobject *z;
941 int size_b, i;
942
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000943 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000944 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000945 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000946 return NULL;
947 }
948
949 z = (longobject *)newlongobject(1L);
950
951 INCREF(a);
952 for (i = 0; i < size_b; ++i) {
953 digit bi = b->ob_digit[i];
954 int j;
955
956 for (j = 0; j < SHIFT; ++j) {
957 longobject *temp;
958
959 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000960 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000961 DECREF(z);
962 z = temp;
963 if (z == NULL)
964 break;
965 }
966 bi >>= 1;
967 if (bi == 0 && i+1 == size_b)
968 break;
Guido van Rossume32e0141992-01-19 16:31:05 +0000969 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000970 DECREF(a);
971 a = temp;
972 if (a == NULL) {
973 DECREF(z);
974 z = NULL;
975 break;
976 }
977 }
978 if (a == NULL)
979 break;
980 }
981 XDECREF(a);
982 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000983}
984
985static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +0000986long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000987 longobject *v;
988{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000989 /* Implement ~x as -(x+1) */
990 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +0000991 longobject *w;
992 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000993 if (w == NULL)
994 return NULL;
995 x = (longobject *) long_add(v, w);
996 DECREF(w);
997 if (x == NULL)
998 return NULL;
999 if (x->ob_size != 0)
1000 x->ob_size = -(x->ob_size);
1001 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001002}
1003
1004static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001005long_pos(v)
1006 longobject *v;
1007{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001008 INCREF(v);
1009 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001010}
1011
1012static object *
1013long_neg(v)
1014 longobject *v;
1015{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001016 longobject *z;
1017 int i, n;
1018 n = ABS(v->ob_size);
1019 if (n == 0) {
1020 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001021 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001022 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001023 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001024 z = alloclongobject(ABS(n));
1025 if (z == NULL)
1026 return NULL;
1027 for (i = 0; i < n; i++)
1028 z->ob_digit[i] = v->ob_digit[i];
1029 z->ob_size = -(v->ob_size);
1030 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001031}
1032
1033static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001034long_abs(v)
1035 longobject *v;
1036{
1037 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001038 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001039 else {
1040 INCREF(v);
1041 return (object *)v;
1042 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001043}
1044
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001045static int
1046long_nonzero(v)
1047 longobject *v;
1048{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001049 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001050}
1051
1052static object *
1053long_rshift(a, b)
1054 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001055 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001056{
1057 longobject *z;
1058 long shiftby;
1059 int newsize, wordshift, loshift, hishift, i, j;
1060 digit lomask, himask;
1061
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001062 if (a->ob_size < 0) {
1063 /* Right shifting negative numbers is harder */
1064 longobject *a1, *a2, *a3;
1065 a1 = (longobject *) long_invert(a);
1066 if (a1 == NULL) return NULL;
1067 a2 = (longobject *) long_rshift(a1, b);
1068 DECREF(a1);
1069 if (a2 == NULL) return NULL;
1070 a3 = (longobject *) long_invert(a2);
1071 DECREF(a2);
1072 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001073 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001074
1075 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001076 if (shiftby == -1L && err_occurred())
1077 return NULL;
1078 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001079 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001080 return NULL;
1081 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001082 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001083 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001084 if (newsize <= 0) {
1085 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001086 return (object *)z;
1087 }
1088 loshift = shiftby % SHIFT;
1089 hishift = SHIFT - loshift;
1090 lomask = ((digit)1 << hishift) - 1;
1091 himask = MASK ^ lomask;
1092 z = alloclongobject(newsize);
1093 if (z == NULL)
1094 return NULL;
1095 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001096 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001097 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1098 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1099 if (i+1 < newsize)
1100 z->ob_digit[i] |=
1101 (a->ob_digit[j+1] << hishift) & himask;
1102 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001103 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001104}
1105
1106static object *
1107long_lshift(a, b)
1108 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001109 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001110{
1111 longobject *z;
1112 long shiftby;
1113 int newsize, wordshift, loshift, hishift, i, j;
1114 digit lomask, himask;
1115
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001116 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001117 if (shiftby == -1L && err_occurred())
1118 return NULL;
1119 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001120 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001121 return NULL;
1122 }
1123 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001124 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001125 return NULL;
1126 }
1127 if (shiftby % SHIFT == 0) {
1128 wordshift = shiftby / SHIFT;
1129 loshift = 0;
1130 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001131 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001132 lomask = MASK;
1133 himask = 0;
1134 }
1135 else {
1136 wordshift = shiftby / SHIFT + 1;
1137 loshift = SHIFT - shiftby%SHIFT;
1138 hishift = shiftby % SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001139 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001140 lomask = ((digit)1 << hishift) - 1;
1141 himask = MASK ^ lomask;
1142 }
1143 z = alloclongobject(newsize);
1144 if (z == NULL)
1145 return NULL;
1146 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001147 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001148 for (i = 0; i < wordshift; i++)
1149 z->ob_digit[i] = 0;
1150 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1151 if (i > 0)
1152 z->ob_digit[i-1] |=
1153 (a->ob_digit[j] << hishift) & himask;
1154 z->ob_digit[i] =
1155 (a->ob_digit[j] >> loshift) & lomask;
1156 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001157 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001158}
1159
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001160
1161/* Bitwise and/xor/or operations */
1162
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001163#define MAX(x, y) ((x) < (y) ? (y) : (x))
1164#define MIN(x, y) ((x) > (y) ? (y) : (x))
1165
Guido van Rossume32e0141992-01-19 16:31:05 +00001166static object *long_bitwise PROTO((longobject *, int, longobject *));
1167static object *
1168long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001169 longobject *a;
1170 int op; /* '&', '|', '^' */
1171 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001172{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001173 digit maska, maskb; /* 0 or MASK */
1174 int negz;
1175 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001176 longobject *z;
1177 int i;
Guido van Rossum8b27d921992-03-27 17:27:05 +00001178 digit diga, digb;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001179 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001180
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001181 if (a->ob_size < 0) {
1182 a = (longobject *) long_invert(a);
1183 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001184 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001185 else {
1186 INCREF(a);
1187 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001188 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001189 if (b->ob_size < 0) {
1190 b = (longobject *) long_invert(b);
1191 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001192 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001193 else {
1194 INCREF(b);
1195 maskb = 0;
1196 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001197
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001198 size_a = a->ob_size;
1199 size_b = b->ob_size;
1200 size_z = MAX(size_a, size_b);
1201 z = alloclongobject(size_z);
1202 if (a == NULL || b == NULL || z == NULL) {
1203 XDECREF(a);
1204 XDECREF(b);
1205 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001206 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001207 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001208
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001209 negz = 0;
1210 switch (op) {
1211 case '^':
1212 if (maska != maskb) {
1213 maska ^= MASK;
1214 negz = -1;
1215 }
1216 break;
1217 case '&':
1218 if (maska && maskb) {
1219 op = '|';
1220 maska ^= MASK;
1221 maskb ^= MASK;
1222 negz = -1;
1223 }
1224 break;
1225 case '|':
1226 if (maska || maskb) {
1227 op = '&';
1228 maska ^= MASK;
1229 maskb ^= MASK;
1230 negz = -1;
1231 }
1232 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001233 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001234
1235 for (i = 0; i < size_z; ++i) {
1236 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1237 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1238 switch (op) {
1239 case '&': z->ob_digit[i] = diga & digb; break;
1240 case '|': z->ob_digit[i] = diga | digb; break;
1241 case '^': z->ob_digit[i] = diga ^ digb; break;
1242 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001243 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001244
1245 DECREF(a);
1246 DECREF(b);
1247 z = long_normalize(z);
1248 if (negz == 0)
1249 return (object *) z;
1250 v = long_invert(z);
1251 DECREF(z);
1252 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001253}
1254
Guido van Rossumc6913e71991-11-19 20:26:46 +00001255static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001256long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001257 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001258 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001259{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001260 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001261}
1262
1263static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001264long_xor(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001265 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001266 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001267{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001268 return long_bitwise(a, '^', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001269}
1270
1271static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001272long_or(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001273 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001274 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001275{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001276 return long_bitwise(a, '|', b);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001277}
1278
Guido van Rossum234f9421993-06-17 12:35:49 +00001279static int
Guido van Rossume6eefc21992-08-14 12:06:52 +00001280long_coerce(pv, pw)
1281 object **pv;
1282 object **pw;
1283{
1284 if (is_intobject(*pw)) {
1285 *pw = newlongobject(getintvalue(*pw));
1286 INCREF(*pv);
1287 return 0;
1288 }
1289 return 1; /* Can't do it */
1290}
1291
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001292static object *
1293long_int(v)
1294 object *v;
1295{
1296 long x;
1297 x = getlongvalue(v);
1298 if (err_occurred())
1299 return NULL;
1300 return newintobject(x);
1301}
1302
1303static object *
1304long_long(v)
1305 object *v;
1306{
1307 INCREF(v);
1308 return v;
1309}
1310
1311static object *
1312long_float(v)
1313 object *v;
1314{
1315 return newfloatobject(dgetlongvalue(v));
1316}
1317
1318static object *
1319long_oct(v)
1320 object *v;
1321{
1322 return long_format(v, 8);
1323}
1324
1325static object *
1326long_hex(v)
1327 object *v;
1328{
1329 return long_format(v, 16);
1330}
1331
1332
Guido van Rossum8b27d921992-03-27 17:27:05 +00001333#define UF (object* (*) FPROTO((object *))) /* Unary function */
1334#define BF (object* (*) FPROTO((object *, object *))) /* Binary function */
1335#define IF (int (*) FPROTO((object *))) /* Int function */
1336
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001337static number_methods long_as_number = {
Guido van Rossum8b27d921992-03-27 17:27:05 +00001338 BF long_add, /*nb_add*/
1339 BF long_sub, /*nb_subtract*/
1340 BF long_mul, /*nb_multiply*/
1341 BF long_div, /*nb_divide*/
1342 BF long_mod, /*nb_remainder*/
1343 BF long_divmod, /*nb_divmod*/
1344 BF long_pow, /*nb_power*/
1345 UF long_neg, /*nb_negative*/
1346 UF long_pos, /*tp_positive*/
1347 UF long_abs, /*tp_absolute*/
1348 IF long_nonzero,/*tp_nonzero*/
1349 UF long_invert, /*nb_invert*/
1350 BF long_lshift, /*nb_lshift*/
1351 BF long_rshift, /*nb_rshift*/
1352 BF long_and, /*nb_and*/
1353 BF long_xor, /*nb_xor*/
1354 BF long_or, /*nb_or*/
Guido van Rossume6eefc21992-08-14 12:06:52 +00001355 (int (*) FPROTO((object **, object **)))
1356 long_coerce, /*nb_coerce*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001357 UF long_int, /*nb_int*/
1358 UF long_long, /*nb_long*/
1359 UF long_float, /*nb_float*/
1360 UF long_oct, /*nb_oct*/
1361 UF long_hex, /*nb_hex*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001362};
1363
1364typeobject Longtype = {
1365 OB_HEAD_INIT(&Typetype)
1366 0,
1367 "long int",
1368 sizeof(longobject) - sizeof(digit),
1369 sizeof(digit),
1370 long_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001371 0, /*tp_print*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001372 0, /*tp_getattr*/
1373 0, /*tp_setattr*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001374 (int (*) FPROTO((object *, object *)))
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001375 long_compare, /*tp_compare*/
1376 long_repr, /*tp_repr*/
1377 &long_as_number,/*tp_as_number*/
1378 0, /*tp_as_sequence*/
1379 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +00001380 (long (*) FPROTO((object *)))
1381 long_hash, /*tp_hash*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001382};