blob: f98e517b719f0111850b32d23724165f0e3c5838 [file] [log] [blame]
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumedcc38a1991-05-05 20:09:44 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumedcc38a1991-05-05 20:09:44 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumedcc38a1991-05-05 20:09:44 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumedcc38a1991-05-05 20:09:44 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumedcc38a1991-05-05 20:09:44 +000029
30******************************************************************/
31
32/* Long (arbitrary precision) integer object implementation */
33
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000034/* XXX The functional organization of this file is terrible */
35
Guido van Rossumedcc38a1991-05-05 20:09:44 +000036#include "allobjects.h"
37#include "longintrepr.h"
Guido van Rossum687ec181995-03-04 22:43:47 +000038#include "mymath.h"
Guido van Rossumedcc38a1991-05-05 20:09:44 +000039#include <assert.h>
Guido van Rossumeb1fafc1994-08-29 12:47:19 +000040#include <ctype.h>
Guido van Rossumedcc38a1991-05-05 20:09:44 +000041
Guido van Rossume32e0141992-01-19 16:31:05 +000042#define ABS(x) ((x) < 0 ? -(x) : (x))
43
44/* Forward */
45static longobject *long_normalize PROTO((longobject *));
46static longobject *mul1 PROTO((longobject *, wdigit));
47static longobject *muladd1 PROTO((longobject *, wdigit, wdigit));
48static longobject *divrem1 PROTO((longobject *, wdigit, digit *));
Guido van Rossumb73cc041993-11-01 16:28:59 +000049static object *long_format PROTO((object *aa, int base));
Guido van Rossume32e0141992-01-19 16:31:05 +000050
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000051static int ticker; /* XXX Could be shared with ceval? */
52
Guido van Rossumeb1fafc1994-08-29 12:47:19 +000053#define SIGCHECK(block) \
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000054 if (--ticker < 0) { \
55 ticker = 100; \
Guido van Rossumeb1fafc1994-08-29 12:47:19 +000056 if (sigcheck()) { block; } \
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000057 }
58
Guido van Rossumedcc38a1991-05-05 20:09:44 +000059/* Normalize (remove leading zeros from) a long int object.
60 Doesn't attempt to free the storage--in most cases, due to the nature
61 of the algorithms used, this could save at most be one word anyway. */
62
Guido van Rossum4c260ff1992-01-14 18:36:43 +000063static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +000064long_normalize(v)
65 register longobject *v;
66{
Guido van Rossum4c260ff1992-01-14 18:36:43 +000067 int j = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +000068 register int i = j;
69
70 while (i > 0 && v->ob_digit[i-1] == 0)
71 --i;
72 if (i != j)
Guido van Rossum4c260ff1992-01-14 18:36:43 +000073 v->ob_size = (v->ob_size < 0) ? -(i) : i;
Guido van Rossumedcc38a1991-05-05 20:09:44 +000074 return v;
75}
76
77/* Allocate a new long int object with size digits.
78 Return NULL and set exception if we run out of memory. */
79
80longobject *
81alloclongobject(size)
82 int size;
83{
84 return NEWVAROBJ(longobject, &Longtype, size);
85}
86
87/* Create a new long int object from a C long int */
88
89object *
90newlongobject(ival)
91 long ival;
92{
Guido van Rossum472c04f1996-12-05 21:57:21 +000093 /* Assume a C long fits in at most 5 'digits' */
94 /* Works on both 32- and 64-bit machines */
95 longobject *v = alloclongobject(5);
Guido van Rossumedcc38a1991-05-05 20:09:44 +000096 if (v != NULL) {
Guido van Rossum472c04f1996-12-05 21:57:21 +000097 unsigned long t = ival;
98 int i;
Guido van Rossumedcc38a1991-05-05 20:09:44 +000099 if (ival < 0) {
Guido van Rossum472c04f1996-12-05 21:57:21 +0000100 t = -ival;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000101 v->ob_size = -(v->ob_size);
Guido van Rossum472c04f1996-12-05 21:57:21 +0000102 }
103 for (i = 0; i < 5; i++) {
104 v->ob_digit[i] = t & MASK;
105 t >>= SHIFT;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000106 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000107 v = long_normalize(v);
108 }
109 return (object *)v;
110}
111
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000112/* Create a new long int object from a C double */
113
114object *
Guido van Rossum687ec181995-03-04 22:43:47 +0000115#ifdef MPW
116dnewlongobject(double dval)
117#else
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000118dnewlongobject(dval)
119 double dval;
Guido van Rossum687ec181995-03-04 22:43:47 +0000120#endif /* MPW */
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000121{
122 longobject *v;
123 double frac;
124 int i, ndig, expo, neg;
125 neg = 0;
126 if (dval < 0.0) {
127 neg = 1;
128 dval = -dval;
129 }
130 frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
131 if (expo <= 0)
132 return newlongobject(0L);
133 ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
134 v = alloclongobject(ndig);
135 if (v == NULL)
136 return NULL;
137 frac = ldexp(frac, (expo-1) % SHIFT + 1);
138 for (i = ndig; --i >= 0; ) {
139 long bits = (long)frac;
140 v->ob_digit[i] = bits;
141 frac = frac - (double)bits;
142 frac = ldexp(frac, SHIFT);
143 }
144 if (neg)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000145 v->ob_size = -(v->ob_size);
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000146 return (object *)v;
147}
148
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000149/* Get a C long int from a long int object.
150 Returns -1 and sets an error condition if overflow occurs. */
151
152long
153getlongvalue(vv)
154 object *vv;
155{
156 register longobject *v;
157 long x, prev;
158 int i, sign;
159
160 if (vv == NULL || !is_longobject(vv)) {
161 err_badcall();
162 return -1;
163 }
164 v = (longobject *)vv;
165 i = v->ob_size;
166 sign = 1;
167 x = 0;
168 if (i < 0) {
169 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000170 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000171 }
172 while (--i >= 0) {
173 prev = x;
174 x = (x << SHIFT) + v->ob_digit[i];
175 if ((x >> SHIFT) != prev) {
Guido van Rossum03093a21994-09-28 15:51:32 +0000176 err_setstr(OverflowError,
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000177 "long int too long to convert");
178 return -1;
179 }
180 }
181 return x * sign;
182}
183
184/* Get a C double from a long int object. No overflow check. */
185
186double
187dgetlongvalue(vv)
188 object *vv;
189{
190 register longobject *v;
191 double x;
192 double multiplier = (double) (1L << SHIFT);
193 int i, sign;
194
195 if (vv == NULL || !is_longobject(vv)) {
196 err_badcall();
197 return -1;
198 }
199 v = (longobject *)vv;
200 i = v->ob_size;
201 sign = 1;
202 x = 0.0;
203 if (i < 0) {
204 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000205 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000206 }
207 while (--i >= 0) {
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000208 x = x*multiplier + (double)v->ob_digit[i];
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000209 }
210 return x * sign;
211}
212
213/* Multiply by a single digit, ignoring the sign. */
214
Guido van Rossume32e0141992-01-19 16:31:05 +0000215static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000216mul1(a, n)
217 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000218 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000219{
220 return muladd1(a, n, (digit)0);
221}
222
223/* Multiply by a single digit and add a single digit, ignoring the sign. */
224
Guido van Rossume32e0141992-01-19 16:31:05 +0000225static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000226muladd1(a, n, extra)
227 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000228 wdigit n;
229 wdigit extra;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000230{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000231 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000232 longobject *z = alloclongobject(size_a+1);
233 twodigits carry = extra;
234 int i;
235
236 if (z == NULL)
237 return NULL;
238 for (i = 0; i < size_a; ++i) {
239 carry += (twodigits)a->ob_digit[i] * n;
240 z->ob_digit[i] = carry & MASK;
241 carry >>= SHIFT;
242 }
243 z->ob_digit[i] = carry;
244 return long_normalize(z);
245}
246
247/* Divide a long integer by a digit, returning both the quotient
248 (as function result) and the remainder (through *prem).
249 The sign of a is ignored; n should not be zero. */
250
Guido van Rossume32e0141992-01-19 16:31:05 +0000251static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000252divrem1(a, n, prem)
253 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000254 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000255 digit *prem;
256{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000257 int size = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000258 longobject *z;
259 int i;
260 twodigits rem = 0;
261
262 assert(n > 0 && n <= MASK);
263 z = alloclongobject(size);
264 if (z == NULL)
265 return NULL;
266 for (i = size; --i >= 0; ) {
267 rem = (rem << SHIFT) + a->ob_digit[i];
268 z->ob_digit[i] = rem/n;
269 rem %= n;
270 }
271 *prem = rem;
272 return long_normalize(z);
273}
274
275/* Convert a long int object to a string, using a given conversion base.
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000276 Return a string object.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000277 If base is 8 or 16, add the proper prefix '0' or '0x'.
278 External linkage: used in bltinmodule.c by hex() and oct(). */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000279
Guido van Rossum234f9421993-06-17 12:35:49 +0000280static object *
Guido van Rossume32e0141992-01-19 16:31:05 +0000281long_format(aa, base)
282 object *aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000283 int base;
284{
Guido van Rossume32e0141992-01-19 16:31:05 +0000285 register longobject *a = (longobject *)aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000286 stringobject *str;
287 int i;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000288 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000289 char *p;
290 int bits;
291 char sign = '\0';
Guido van Rossume32e0141992-01-19 16:31:05 +0000292
293 if (a == NULL || !is_longobject(a)) {
294 err_badcall();
295 return NULL;
296 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000297 assert(base >= 2 && base <= 36);
298
299 /* Compute a rough upper bound for the length of the string */
300 i = base;
301 bits = 0;
302 while (i > 1) {
303 ++bits;
304 i >>= 1;
305 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000306 i = 6 + (size_a*SHIFT + bits-1) / bits;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000307 str = (stringobject *) newsizedstringobject((char *)0, i);
308 if (str == NULL)
309 return NULL;
310 p = GETSTRINGVALUE(str) + i;
311 *p = '\0';
Guido van Rossumc6913e71991-11-19 20:26:46 +0000312 *--p = 'L';
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000313 if (a->ob_size < 0)
314 sign = '-';
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000315
316 INCREF(a);
317 do {
318 digit rem;
319 longobject *temp = divrem1(a, (digit)base, &rem);
320 if (temp == NULL) {
321 DECREF(a);
322 DECREF(str);
323 return NULL;
324 }
325 if (rem < 10)
326 rem += '0';
327 else
328 rem += 'A'-10;
329 assert(p > GETSTRINGVALUE(str));
330 *--p = rem;
331 DECREF(a);
332 a = temp;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000333 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000334 DECREF(a);
335 DECREF(str);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000336 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000337 })
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000338 } while (ABS(a->ob_size) != 0);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000339 DECREF(a);
Guido van Rossum2c475421992-08-14 15:13:07 +0000340 if (base == 8) {
341 if (size_a != 0)
342 *--p = '0';
343 }
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000344 else if (base == 16) {
345 *--p = 'x';
346 *--p = '0';
347 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000348 else if (base != 10) {
349 *--p = '#';
350 *--p = '0' + base%10;
351 if (base > 10)
352 *--p = '0' + base/10;
353 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000354 if (sign)
355 *--p = sign;
356 if (p != GETSTRINGVALUE(str)) {
357 char *q = GETSTRINGVALUE(str);
358 assert(p > q);
359 do {
360 } while ((*q++ = *p++) != '\0');
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000361 q--;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000362 resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
363 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000364 return (object *)str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000365}
366
Guido van Rossum3535f6e1995-01-17 16:34:13 +0000367#if 0
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000368/* Convert a string to a long int object, in a given base.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000369 Base zero implies a default depending on the number.
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000370 External linkage: used in compile.c and stropmodule.c. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000371
372object *
373long_scan(str, base)
374 char *str;
375 int base;
376{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000377 return long_escan(str, (char **)NULL, base);
378}
Guido van Rossum3535f6e1995-01-17 16:34:13 +0000379#endif
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000380
381object *
382long_escan(str, pend, base)
383 char *str;
384 char **pend;
385 int base;
386{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000387 int sign = 1;
388 longobject *z;
389
Guido van Rossum472c04f1996-12-05 21:57:21 +0000390 if ((base != 0 && base < 2) || base > 36) {
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000391 err_setstr(ValueError, "invalid base for long literal");
392 return NULL;
393 }
Guido van Rossum9fa2c111995-02-10 17:00:37 +0000394 while (*str != '\0' && isspace(Py_CHARMASK(*str)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000395 str++;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000396 if (*str == '+')
397 ++str;
398 else if (*str == '-') {
399 ++str;
400 sign = -1;
401 }
Guido van Rossum9fa2c111995-02-10 17:00:37 +0000402 while (*str != '\0' && isspace(Py_CHARMASK(*str)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000403 str++;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000404 if (base == 0) {
405 if (str[0] != '0')
406 base = 10;
407 else if (str[1] == 'x' || str[1] == 'X')
408 base = 16;
409 else
410 base = 8;
411 }
412 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
413 str += 2;
414 z = alloclongobject(0);
415 for ( ; z != NULL; ++str) {
416 int k = -1;
417 longobject *temp;
418
419 if (*str <= '9')
420 k = *str - '0';
421 else if (*str >= 'a')
422 k = *str - 'a' + 10;
423 else if (*str >= 'A')
424 k = *str - 'A' + 10;
425 if (k < 0 || k >= base)
426 break;
427 temp = muladd1(z, (digit)base, (digit)k);
428 DECREF(z);
429 z = temp;
430 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000431 if (sign < 0 && z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000432 z->ob_size = -(z->ob_size);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000433 if (pend)
434 *pend = str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000435 return (object *) z;
436}
437
438static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
Guido van Rossumc6913e71991-11-19 20:26:46 +0000439static object *long_pos PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000440static long_divrem PROTO((longobject *, longobject *,
441 longobject **, longobject **));
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000442
443/* Long division with remainder, top-level routine */
444
Guido van Rossume32e0141992-01-19 16:31:05 +0000445static int
446long_divrem(a, b, pdiv, prem)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000447 longobject *a, *b;
Guido van Rossume32e0141992-01-19 16:31:05 +0000448 longobject **pdiv;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000449 longobject **prem;
450{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000451 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000452 longobject *z;
453
454 if (size_b == 0) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000455 err_setstr(ZeroDivisionError, "long division or modulo");
456 return -1;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000457 }
458 if (size_a < size_b ||
Guido van Rossum472c04f1996-12-05 21:57:21 +0000459 (size_a == size_b &&
460 a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000461 /* |a| < |b|. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000462 *pdiv = alloclongobject(0);
463 INCREF(a);
464 *prem = (longobject *) a;
465 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000466 }
467 if (size_b == 1) {
468 digit rem = 0;
469 z = divrem1(a, b->ob_digit[0], &rem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000470 if (z == NULL)
471 return -1;
472 *prem = (longobject *) newlongobject((long)rem);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000473 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000474 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000475 z = x_divrem(a, b, prem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000476 if (z == NULL)
477 return -1;
478 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000479 /* Set the signs.
480 The quotient z has the sign of a*b;
481 the remainder r has the sign of a,
482 so a = b*z + r. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000483 if ((a->ob_size < 0) != (b->ob_size < 0))
484 z->ob_size = -(z->ob_size);
485 if (a->ob_size < 0 && (*prem)->ob_size != 0)
486 (*prem)->ob_size = -((*prem)->ob_size);
487 *pdiv = z;
488 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000489}
490
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000491/* Unsigned long division with remainder -- the algorithm */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000492
493static longobject *
494x_divrem(v1, w1, prem)
495 longobject *v1, *w1;
496 longobject **prem;
497{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000498 int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000499 digit d = (twodigits)BASE / (w1->ob_digit[size_w-1] + 1);
500 longobject *v = mul1(v1, d);
501 longobject *w = mul1(w1, d);
502 longobject *a;
503 int j, k;
504
505 if (v == NULL || w == NULL) {
506 XDECREF(v);
507 XDECREF(w);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000508 return NULL;
509 }
510
511 assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000512 assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000513 assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000514
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000515 size_v = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000516 a = alloclongobject(size_v - size_w + 1);
517
518 for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
519 digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
520 twodigits q;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000521 stwodigits carry = 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000522 int i;
523
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000524 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000525 DECREF(a);
526 a = NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000527 break;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000528 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000529 if (vj == w->ob_digit[size_w-1])
530 q = MASK;
531 else
532 q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
533 w->ob_digit[size_w-1];
534
535 while (w->ob_digit[size_w-2]*q >
536 ((
537 ((twodigits)vj << SHIFT)
538 + v->ob_digit[j-1]
539 - q*w->ob_digit[size_w-1]
540 ) << SHIFT)
541 + v->ob_digit[j-2])
542 --q;
543
544 for (i = 0; i < size_w && i+k < size_v; ++i) {
545 twodigits z = w->ob_digit[i] * q;
546 digit zz = z >> SHIFT;
547 carry += v->ob_digit[i+k] - z + ((twodigits)zz << SHIFT);
548 v->ob_digit[i+k] = carry & MASK;
549 carry = (carry >> SHIFT) - zz;
550 }
551
552 if (i+k < size_v) {
553 carry += v->ob_digit[i+k];
554 v->ob_digit[i+k] = 0;
555 }
556
557 if (carry == 0)
558 a->ob_digit[k] = q;
559 else {
560 assert(carry == -1);
561 a->ob_digit[k] = q-1;
562 carry = 0;
563 for (i = 0; i < size_w && i+k < size_v; ++i) {
564 carry += v->ob_digit[i+k] + w->ob_digit[i];
565 v->ob_digit[i+k] = carry & MASK;
566 carry >>= SHIFT;
567 }
568 }
569 } /* for j, k */
570
Guido van Rossumc206c761995-01-10 15:23:19 +0000571 if (a == NULL)
572 *prem = NULL;
573 else {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000574 a = long_normalize(a);
Guido van Rossume32e0141992-01-19 16:31:05 +0000575 *prem = divrem1(v, d, &d);
576 /* d receives the (unused) remainder */
577 if (*prem == NULL) {
578 DECREF(a);
579 a = NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000580 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000581 }
582 DECREF(v);
583 DECREF(w);
584 return a;
585}
586
587/* Methods */
588
Guido van Rossume32e0141992-01-19 16:31:05 +0000589/* Forward */
Guido van Rossum8b27d921992-03-27 17:27:05 +0000590static void long_dealloc PROTO((object *));
Guido van Rossum8b27d921992-03-27 17:27:05 +0000591static object *long_repr PROTO((object *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000592static int long_compare PROTO((longobject *, longobject *));
Guido van Rossum9bfef441993-03-29 10:43:31 +0000593static long long_hash PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000594
595static object *long_add PROTO((longobject *, longobject *));
596static object *long_sub PROTO((longobject *, longobject *));
597static object *long_mul PROTO((longobject *, longobject *));
598static object *long_div PROTO((longobject *, longobject *));
599static object *long_mod PROTO((longobject *, longobject *));
600static object *long_divmod PROTO((longobject *, longobject *));
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000601static object *long_pow PROTO((longobject *, longobject *, longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000602static object *long_neg PROTO((longobject *));
603static object *long_pos PROTO((longobject *));
604static object *long_abs PROTO((longobject *));
605static int long_nonzero PROTO((longobject *));
606static object *long_invert PROTO((longobject *));
607static object *long_lshift PROTO((longobject *, longobject *));
608static object *long_rshift PROTO((longobject *, longobject *));
609static object *long_and PROTO((longobject *, longobject *));
610static object *long_xor PROTO((longobject *, longobject *));
611static object *long_or PROTO((longobject *, longobject *));
612
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000613static void
614long_dealloc(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000615 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000616{
617 DEL(v);
618}
619
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000620static object *
621long_repr(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000622 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000623{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000624 return long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000625}
626
627static int
628long_compare(a, b)
629 longobject *a, *b;
630{
631 int sign;
632
Guido van Rossumc6913e71991-11-19 20:26:46 +0000633 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000634 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000635 sign = 0;
636 else
637 sign = a->ob_size - b->ob_size;
638 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000639 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000640 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000641 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
642 ;
643 if (i < 0)
644 sign = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000645 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000646 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000647 if (a->ob_size < 0)
648 sign = -sign;
649 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000650 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000651 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000652}
653
Guido van Rossum9bfef441993-03-29 10:43:31 +0000654static long
655long_hash(v)
656 longobject *v;
657{
658 long x;
659 int i, sign;
660
661 /* This is designed so that Python ints and longs with the
662 same value hash to the same value, otherwise comparisons
663 of mapping keys will turn out weird */
664 i = v->ob_size;
665 sign = 1;
666 x = 0;
667 if (i < 0) {
668 sign = -1;
669 i = -(i);
670 }
671 while (--i >= 0) {
672 /* Force a 32-bit circular shift */
673 x = ((x << SHIFT) & ~MASK) | ((x >> (32-SHIFT)) & MASK);
674 x += v->ob_digit[i];
675 }
676 x = x * sign;
677 if (x == -1)
678 x = -2;
679 return x;
680}
681
682
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000683/* Add the absolute values of two long integers. */
684
685static longobject *x_add PROTO((longobject *, longobject *));
686static longobject *
687x_add(a, b)
688 longobject *a, *b;
689{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000690 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000691 longobject *z;
692 int i;
693 digit carry = 0;
694
695 /* Ensure a is the larger of the two: */
696 if (size_a < size_b) {
697 { longobject *temp = a; a = b; b = temp; }
698 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
699 }
700 z = alloclongobject(size_a+1);
701 if (z == NULL)
702 return NULL;
703 for (i = 0; i < size_b; ++i) {
704 carry += a->ob_digit[i] + b->ob_digit[i];
705 z->ob_digit[i] = carry & MASK;
706 /* The following assumes unsigned shifts don't
707 propagate the sign bit. */
708 carry >>= SHIFT;
709 }
710 for (; i < size_a; ++i) {
711 carry += a->ob_digit[i];
712 z->ob_digit[i] = carry & MASK;
713 carry >>= SHIFT;
714 }
715 z->ob_digit[i] = carry;
716 return long_normalize(z);
717}
718
719/* Subtract the absolute values of two integers. */
720
721static longobject *x_sub PROTO((longobject *, longobject *));
722static longobject *
723x_sub(a, b)
724 longobject *a, *b;
725{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000726 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000727 longobject *z;
728 int i;
729 int sign = 1;
730 digit borrow = 0;
731
732 /* Ensure a is the larger of the two: */
733 if (size_a < size_b) {
734 sign = -1;
735 { longobject *temp = a; a = b; b = temp; }
736 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
737 }
738 else if (size_a == size_b) {
739 /* Find highest digit where a and b differ: */
740 i = size_a;
741 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
742 ;
743 if (i < 0)
744 return alloclongobject(0);
745 if (a->ob_digit[i] < b->ob_digit[i]) {
746 sign = -1;
747 { longobject *temp = a; a = b; b = temp; }
748 }
749 size_a = size_b = i+1;
750 }
751 z = alloclongobject(size_a);
752 if (z == NULL)
753 return NULL;
754 for (i = 0; i < size_b; ++i) {
755 /* The following assumes unsigned arithmetic
756 works module 2**N for some N>SHIFT. */
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000757 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000758 z->ob_digit[i] = borrow & MASK;
759 borrow >>= SHIFT;
760 borrow &= 1; /* Keep only one sign bit */
761 }
762 for (; i < size_a; ++i) {
763 borrow = a->ob_digit[i] - borrow;
764 z->ob_digit[i] = borrow & MASK;
765 borrow >>= SHIFT;
766 }
767 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000768 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000769 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000770 return long_normalize(z);
771}
772
773static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000774long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000775 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000776 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000777{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000778 longobject *z;
779
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000780 if (a->ob_size < 0) {
781 if (b->ob_size < 0) {
782 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000783 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000784 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000785 }
786 else
787 z = x_sub(b, a);
788 }
789 else {
790 if (b->ob_size < 0)
791 z = x_sub(a, b);
792 else
793 z = x_add(a, b);
794 }
795 return (object *)z;
796}
797
798static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000799long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000800 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000801 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000802{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000803 longobject *z;
804
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000805 if (a->ob_size < 0) {
806 if (b->ob_size < 0)
807 z = x_sub(a, b);
808 else
809 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000810 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000811 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000812 }
813 else {
814 if (b->ob_size < 0)
815 z = x_add(a, b);
816 else
817 z = x_sub(a, b);
818 }
819 return (object *)z;
820}
821
822static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000823long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000824 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000825 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000826{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000827 int size_a;
828 int size_b;
829 longobject *z;
830 int i;
831
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000832 size_a = ABS(a->ob_size);
833 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000834 z = alloclongobject(size_a + size_b);
835 if (z == NULL)
836 return NULL;
837 for (i = 0; i < z->ob_size; ++i)
838 z->ob_digit[i] = 0;
839 for (i = 0; i < size_a; ++i) {
840 twodigits carry = 0;
841 twodigits f = a->ob_digit[i];
842 int j;
843
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000844 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000845 DECREF(z);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000846 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000847 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000848 for (j = 0; j < size_b; ++j) {
849 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
850 z->ob_digit[i+j] = carry & MASK;
851 carry >>= SHIFT;
852 }
853 for (; carry != 0; ++j) {
854 assert(i+j < z->ob_size);
855 carry += z->ob_digit[i+j];
856 z->ob_digit[i+j] = carry & MASK;
857 carry >>= SHIFT;
858 }
859 }
860 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000861 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000862 if (b->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000863 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000864 return (object *) long_normalize(z);
865}
866
Guido van Rossume32e0141992-01-19 16:31:05 +0000867/* The / and % operators are now defined in terms of divmod().
868 The expression a mod b has the value a - b*floor(a/b).
869 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000870 |a| by |b|, with the sign of a. This is also expressed
871 as a - b*trunc(a/b), if trunc truncates towards zero.
872 Some examples:
873 a b a rem b a mod b
874 13 10 3 3
875 -13 10 -3 7
876 13 -10 3 -7
877 -13 -10 -3 -3
878 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000879 have different signs. We then subtract one from the 'div'
880 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000881
Guido van Rossume32e0141992-01-19 16:31:05 +0000882static int l_divmod PROTO((longobject *, longobject *,
883 longobject **, longobject **));
884static int
885l_divmod(v, w, pdiv, pmod)
886 longobject *v;
887 longobject *w;
888 longobject **pdiv;
889 longobject **pmod;
890{
891 longobject *div, *mod;
892
893 if (long_divrem(v, w, &div, &mod) < 0)
894 return -1;
Guido van Rossum472c04f1996-12-05 21:57:21 +0000895 if ((mod->ob_size < 0 && w->ob_size > 0) ||
896 (mod->ob_size > 0 && w->ob_size < 0)) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000897 longobject *temp;
898 longobject *one;
899 temp = (longobject *) long_add(mod, w);
900 DECREF(mod);
901 mod = temp;
902 if (mod == NULL) {
903 DECREF(div);
904 return -1;
905 }
906 one = (longobject *) newlongobject(1L);
907 if (one == NULL ||
908 (temp = (longobject *) long_sub(div, one)) == NULL) {
909 DECREF(mod);
910 DECREF(div);
Guido van Rossume5372401993-03-16 12:15:04 +0000911 XDECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000912 return -1;
913 }
Guido van Rossume5372401993-03-16 12:15:04 +0000914 DECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000915 DECREF(div);
916 div = temp;
917 }
918 *pdiv = div;
919 *pmod = mod;
920 return 0;
921}
922
923static object *
924long_div(v, w)
925 longobject *v;
926 longobject *w;
927{
928 longobject *div, *mod;
929 if (l_divmod(v, w, &div, &mod) < 0)
930 return NULL;
931 DECREF(mod);
932 return (object *)div;
933}
934
935static object *
936long_mod(v, w)
937 longobject *v;
938 longobject *w;
939{
940 longobject *div, *mod;
941 if (l_divmod(v, w, &div, &mod) < 0)
942 return NULL;
943 DECREF(div);
944 return (object *)mod;
945}
946
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000947static object *
948long_divmod(v, w)
949 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000950 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000951{
952 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000953 longobject *div, *mod;
954 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000955 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000956 z = newtupleobject(2);
957 if (z != NULL) {
958 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000959 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000960 }
961 else {
962 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000963 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000964 }
965 return z;
966}
967
968static object *
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000969long_pow(a, b, c)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000970 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000971 longobject *b;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000972 longobject *c;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000973{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000974 longobject *z, *div, *mod;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000975 int size_b, i;
976
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000977 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000978 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000979 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000980 return NULL;
981 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000982 z = (longobject *)newlongobject(1L);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000983 INCREF(a);
984 for (i = 0; i < size_b; ++i) {
985 digit bi = b->ob_digit[i];
986 int j;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000987
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000988 for (j = 0; j < SHIFT; ++j) {
989 longobject *temp;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000990
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000991 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000992 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000993 DECREF(z);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000994 if ((object*)c!=None && temp!=NULL) {
995 l_divmod(temp, c, &div, &mod);
996 XDECREF(div);
997 DECREF(temp);
998 temp = mod;
999 }
1000 z = temp;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001001 if (z == NULL)
1002 break;
1003 }
1004 bi >>= 1;
1005 if (bi == 0 && i+1 == size_b)
1006 break;
Guido van Rossume32e0141992-01-19 16:31:05 +00001007 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001008 DECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001009 if ((object*)c!=None && temp!=NULL) {
1010 l_divmod(temp, c, &div, &mod);
1011 XDECREF(div);
1012 DECREF(temp);
1013 temp = mod;
1014 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001015 a = temp;
1016 if (a == NULL) {
1017 DECREF(z);
1018 z = NULL;
1019 break;
1020 }
1021 }
Guido van Rossumc206c761995-01-10 15:23:19 +00001022 if (a == NULL || z == NULL)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001023 break;
1024 }
1025 XDECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001026 if ((object*)c!=None && z!=NULL) {
1027 l_divmod(z, c, &div, &mod);
1028 XDECREF(div);
1029 DECREF(z);
1030 z=mod;
1031 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001032 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001033}
1034
1035static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001036long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001037 longobject *v;
1038{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001039 /* Implement ~x as -(x+1) */
1040 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +00001041 longobject *w;
1042 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001043 if (w == NULL)
1044 return NULL;
1045 x = (longobject *) long_add(v, w);
1046 DECREF(w);
1047 if (x == NULL)
1048 return NULL;
1049 if (x->ob_size != 0)
1050 x->ob_size = -(x->ob_size);
1051 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001052}
1053
1054static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001055long_pos(v)
1056 longobject *v;
1057{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001058 INCREF(v);
1059 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001060}
1061
1062static object *
1063long_neg(v)
1064 longobject *v;
1065{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001066 longobject *z;
1067 int i, n;
1068 n = ABS(v->ob_size);
1069 if (n == 0) {
1070 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001071 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001072 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001073 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001074 z = alloclongobject(ABS(n));
1075 if (z == NULL)
1076 return NULL;
1077 for (i = 0; i < n; i++)
1078 z->ob_digit[i] = v->ob_digit[i];
1079 z->ob_size = -(v->ob_size);
1080 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001081}
1082
1083static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001084long_abs(v)
1085 longobject *v;
1086{
1087 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001088 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001089 else {
1090 INCREF(v);
1091 return (object *)v;
1092 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001093}
1094
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001095static int
1096long_nonzero(v)
1097 longobject *v;
1098{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001099 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001100}
1101
1102static object *
1103long_rshift(a, b)
1104 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001105 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001106{
1107 longobject *z;
1108 long shiftby;
1109 int newsize, wordshift, loshift, hishift, i, j;
1110 digit lomask, himask;
1111
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001112 if (a->ob_size < 0) {
1113 /* Right shifting negative numbers is harder */
1114 longobject *a1, *a2, *a3;
1115 a1 = (longobject *) long_invert(a);
1116 if (a1 == NULL) return NULL;
1117 a2 = (longobject *) long_rshift(a1, b);
1118 DECREF(a1);
1119 if (a2 == NULL) return NULL;
1120 a3 = (longobject *) long_invert(a2);
1121 DECREF(a2);
1122 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001123 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001124
1125 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001126 if (shiftby == -1L && err_occurred())
1127 return NULL;
1128 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001129 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001130 return NULL;
1131 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001132 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001133 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001134 if (newsize <= 0) {
1135 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001136 return (object *)z;
1137 }
1138 loshift = shiftby % SHIFT;
1139 hishift = SHIFT - loshift;
1140 lomask = ((digit)1 << hishift) - 1;
1141 himask = MASK ^ lomask;
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, j = wordshift; i < newsize; i++, j++) {
1148 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1149 if (i+1 < newsize)
1150 z->ob_digit[i] |=
1151 (a->ob_digit[j+1] << hishift) & himask;
1152 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001153 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001154}
1155
1156static object *
1157long_lshift(a, b)
1158 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001159 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001160{
1161 longobject *z;
1162 long shiftby;
1163 int newsize, wordshift, loshift, hishift, i, j;
1164 digit lomask, himask;
1165
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001166 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001167 if (shiftby == -1L && err_occurred())
1168 return NULL;
1169 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001170 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001171 return NULL;
1172 }
1173 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001174 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001175 return NULL;
1176 }
1177 if (shiftby % SHIFT == 0) {
1178 wordshift = shiftby / SHIFT;
1179 loshift = 0;
1180 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001181 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001182 lomask = MASK;
1183 himask = 0;
1184 }
1185 else {
1186 wordshift = shiftby / SHIFT + 1;
1187 loshift = SHIFT - shiftby%SHIFT;
1188 hishift = shiftby % SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001189 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001190 lomask = ((digit)1 << hishift) - 1;
1191 himask = MASK ^ lomask;
1192 }
1193 z = alloclongobject(newsize);
1194 if (z == NULL)
1195 return NULL;
1196 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001197 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001198 for (i = 0; i < wordshift; i++)
1199 z->ob_digit[i] = 0;
1200 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1201 if (i > 0)
1202 z->ob_digit[i-1] |=
1203 (a->ob_digit[j] << hishift) & himask;
1204 z->ob_digit[i] =
1205 (a->ob_digit[j] >> loshift) & lomask;
1206 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001207 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001208}
1209
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001210
1211/* Bitwise and/xor/or operations */
1212
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001213#define MAX(x, y) ((x) < (y) ? (y) : (x))
1214#define MIN(x, y) ((x) > (y) ? (y) : (x))
1215
Guido van Rossume32e0141992-01-19 16:31:05 +00001216static object *long_bitwise PROTO((longobject *, int, longobject *));
1217static object *
1218long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001219 longobject *a;
1220 int op; /* '&', '|', '^' */
1221 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001222{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001223 digit maska, maskb; /* 0 or MASK */
1224 int negz;
1225 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001226 longobject *z;
1227 int i;
Guido van Rossum8b27d921992-03-27 17:27:05 +00001228 digit diga, digb;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001229 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001230
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001231 if (a->ob_size < 0) {
1232 a = (longobject *) long_invert(a);
1233 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001234 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001235 else {
1236 INCREF(a);
1237 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001238 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001239 if (b->ob_size < 0) {
1240 b = (longobject *) long_invert(b);
1241 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001242 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001243 else {
1244 INCREF(b);
1245 maskb = 0;
1246 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001247
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001248 size_a = a->ob_size;
1249 size_b = b->ob_size;
1250 size_z = MAX(size_a, size_b);
1251 z = alloclongobject(size_z);
1252 if (a == NULL || b == NULL || z == NULL) {
1253 XDECREF(a);
1254 XDECREF(b);
1255 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001256 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001257 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001258
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001259 negz = 0;
1260 switch (op) {
1261 case '^':
1262 if (maska != maskb) {
1263 maska ^= MASK;
1264 negz = -1;
1265 }
1266 break;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001267 case '&':
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001268 if (maska && maskb) {
1269 op = '|';
1270 maska ^= MASK;
1271 maskb ^= MASK;
1272 negz = -1;
1273 }
1274 break;
1275 case '|':
1276 if (maska || maskb) {
1277 op = '&';
1278 maska ^= MASK;
1279 maskb ^= MASK;
1280 negz = -1;
1281 }
1282 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001283 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001284
1285 for (i = 0; i < size_z; ++i) {
1286 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1287 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1288 switch (op) {
1289 case '&': z->ob_digit[i] = diga & digb; break;
1290 case '|': z->ob_digit[i] = diga | digb; break;
1291 case '^': z->ob_digit[i] = diga ^ digb; break;
1292 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001293 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001294
1295 DECREF(a);
1296 DECREF(b);
1297 z = long_normalize(z);
1298 if (negz == 0)
1299 return (object *) z;
1300 v = long_invert(z);
1301 DECREF(z);
1302 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001303}
1304
Guido van Rossumc6913e71991-11-19 20:26:46 +00001305static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001306long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001307 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001308 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001309{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001310 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001311}
1312
1313static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001314long_xor(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001315 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001316 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001317{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001318 return long_bitwise(a, '^', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001319}
1320
1321static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001322long_or(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001323 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001324 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001325{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001326 return long_bitwise(a, '|', b);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001327}
1328
Guido van Rossum234f9421993-06-17 12:35:49 +00001329static int
Guido van Rossume6eefc21992-08-14 12:06:52 +00001330long_coerce(pv, pw)
1331 object **pv;
1332 object **pw;
1333{
1334 if (is_intobject(*pw)) {
1335 *pw = newlongobject(getintvalue(*pw));
1336 INCREF(*pv);
1337 return 0;
1338 }
1339 return 1; /* Can't do it */
1340}
1341
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001342static object *
1343long_int(v)
1344 object *v;
1345{
1346 long x;
1347 x = getlongvalue(v);
1348 if (err_occurred())
1349 return NULL;
1350 return newintobject(x);
1351}
1352
1353static object *
1354long_long(v)
1355 object *v;
1356{
1357 INCREF(v);
1358 return v;
1359}
1360
1361static object *
1362long_float(v)
1363 object *v;
1364{
1365 return newfloatobject(dgetlongvalue(v));
1366}
1367
1368static object *
1369long_oct(v)
1370 object *v;
1371{
1372 return long_format(v, 8);
1373}
1374
1375static object *
1376long_hex(v)
1377 object *v;
1378{
1379 return long_format(v, 16);
1380}
1381
1382
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001383#define UF (unaryfunc)
1384#define BF (binaryfunc)
1385#define TF (ternaryfunc)
1386#define IF (inquiry)
Guido van Rossum8b27d921992-03-27 17:27:05 +00001387
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001388static number_methods long_as_number = {
Guido van Rossum8b27d921992-03-27 17:27:05 +00001389 BF long_add, /*nb_add*/
1390 BF long_sub, /*nb_subtract*/
1391 BF long_mul, /*nb_multiply*/
1392 BF long_div, /*nb_divide*/
1393 BF long_mod, /*nb_remainder*/
1394 BF long_divmod, /*nb_divmod*/
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001395 TF long_pow, /*nb_power*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001396 UF long_neg, /*nb_negative*/
1397 UF long_pos, /*tp_positive*/
1398 UF long_abs, /*tp_absolute*/
1399 IF long_nonzero,/*tp_nonzero*/
1400 UF long_invert, /*nb_invert*/
1401 BF long_lshift, /*nb_lshift*/
1402 BF long_rshift, /*nb_rshift*/
1403 BF long_and, /*nb_and*/
1404 BF long_xor, /*nb_xor*/
1405 BF long_or, /*nb_or*/
Guido van Rossume6eefc21992-08-14 12:06:52 +00001406 (int (*) FPROTO((object **, object **)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001407 (coercion)long_coerce, /*nb_coerce*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001408 UF long_int, /*nb_int*/
1409 UF long_long, /*nb_long*/
1410 UF long_float, /*nb_float*/
1411 UF long_oct, /*nb_oct*/
1412 UF long_hex, /*nb_hex*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001413};
1414
1415typeobject Longtype = {
1416 OB_HEAD_INIT(&Typetype)
1417 0,
1418 "long int",
1419 sizeof(longobject) - sizeof(digit),
1420 sizeof(digit),
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001421 (destructor)long_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001422 0, /*tp_print*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001423 0, /*tp_getattr*/
1424 0, /*tp_setattr*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001425 (int (*) FPROTO((object *, object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001426 (cmpfunc)long_compare, /*tp_compare*/
1427 (reprfunc)long_repr, /*tp_repr*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001428 &long_as_number,/*tp_as_number*/
1429 0, /*tp_as_sequence*/
1430 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +00001431 (long (*) FPROTO((object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001432 (hashfunc)long_hash, /*tp_hash*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001433};