blob: 6db4ff99d1ff9f22e6f1971c6c8b214f3290188f [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{
93 /* Assume a C long fits in at most 3 'digits' */
Guido van Rossumeb1fafc1994-08-29 12:47:19 +000094 /* XXX On 64 bit machines this isn't true!!! */
Guido van Rossumedcc38a1991-05-05 20:09:44 +000095 longobject *v = alloclongobject(3);
96 if (v != NULL) {
97 if (ival < 0) {
98 ival = -ival;
Guido van Rossum4c260ff1992-01-14 18:36:43 +000099 v->ob_size = -(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000100 }
101 v->ob_digit[0] = ival & MASK;
102 v->ob_digit[1] = (ival >> SHIFT) & MASK;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000103 v->ob_digit[2] = ((unsigned long)ival >> (2*SHIFT)) & MASK;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000104 v = long_normalize(v);
105 }
106 return (object *)v;
107}
108
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000109/* Create a new long int object from a C double */
110
111object *
Guido van Rossum687ec181995-03-04 22:43:47 +0000112#ifdef MPW
113dnewlongobject(double dval)
114#else
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000115dnewlongobject(dval)
116 double dval;
Guido van Rossum687ec181995-03-04 22:43:47 +0000117#endif /* MPW */
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000118{
119 longobject *v;
120 double frac;
121 int i, ndig, expo, neg;
122 neg = 0;
123 if (dval < 0.0) {
124 neg = 1;
125 dval = -dval;
126 }
127 frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
128 if (expo <= 0)
129 return newlongobject(0L);
130 ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
131 v = alloclongobject(ndig);
132 if (v == NULL)
133 return NULL;
134 frac = ldexp(frac, (expo-1) % SHIFT + 1);
135 for (i = ndig; --i >= 0; ) {
136 long bits = (long)frac;
137 v->ob_digit[i] = bits;
138 frac = frac - (double)bits;
139 frac = ldexp(frac, SHIFT);
140 }
141 if (neg)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000142 v->ob_size = -(v->ob_size);
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000143 return (object *)v;
144}
145
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000146/* Get a C long int from a long int object.
147 Returns -1 and sets an error condition if overflow occurs. */
148
149long
150getlongvalue(vv)
151 object *vv;
152{
153 register longobject *v;
154 long x, prev;
155 int i, sign;
156
157 if (vv == NULL || !is_longobject(vv)) {
158 err_badcall();
159 return -1;
160 }
161 v = (longobject *)vv;
162 i = v->ob_size;
163 sign = 1;
164 x = 0;
165 if (i < 0) {
166 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000167 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000168 }
169 while (--i >= 0) {
170 prev = x;
171 x = (x << SHIFT) + v->ob_digit[i];
172 if ((x >> SHIFT) != prev) {
Guido van Rossum03093a21994-09-28 15:51:32 +0000173 err_setstr(OverflowError,
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000174 "long int too long to convert");
175 return -1;
176 }
177 }
178 return x * sign;
179}
180
181/* Get a C double from a long int object. No overflow check. */
182
183double
184dgetlongvalue(vv)
185 object *vv;
186{
187 register longobject *v;
188 double x;
189 double multiplier = (double) (1L << SHIFT);
190 int i, sign;
191
192 if (vv == NULL || !is_longobject(vv)) {
193 err_badcall();
194 return -1;
195 }
196 v = (longobject *)vv;
197 i = v->ob_size;
198 sign = 1;
199 x = 0.0;
200 if (i < 0) {
201 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000202 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000203 }
204 while (--i >= 0) {
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000205 x = x*multiplier + (double)v->ob_digit[i];
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000206 }
207 return x * sign;
208}
209
210/* Multiply by a single digit, ignoring the sign. */
211
Guido van Rossume32e0141992-01-19 16:31:05 +0000212static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000213mul1(a, n)
214 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000215 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000216{
217 return muladd1(a, n, (digit)0);
218}
219
220/* Multiply by a single digit and add a single digit, ignoring the sign. */
221
Guido van Rossume32e0141992-01-19 16:31:05 +0000222static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000223muladd1(a, n, extra)
224 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000225 wdigit n;
226 wdigit extra;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000227{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000228 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000229 longobject *z = alloclongobject(size_a+1);
230 twodigits carry = extra;
231 int i;
232
233 if (z == NULL)
234 return NULL;
235 for (i = 0; i < size_a; ++i) {
236 carry += (twodigits)a->ob_digit[i] * n;
237 z->ob_digit[i] = carry & MASK;
238 carry >>= SHIFT;
239 }
240 z->ob_digit[i] = carry;
241 return long_normalize(z);
242}
243
244/* Divide a long integer by a digit, returning both the quotient
245 (as function result) and the remainder (through *prem).
246 The sign of a is ignored; n should not be zero. */
247
Guido van Rossume32e0141992-01-19 16:31:05 +0000248static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000249divrem1(a, n, prem)
250 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000251 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000252 digit *prem;
253{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000254 int size = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000255 longobject *z;
256 int i;
257 twodigits rem = 0;
258
259 assert(n > 0 && n <= MASK);
260 z = alloclongobject(size);
261 if (z == NULL)
262 return NULL;
263 for (i = size; --i >= 0; ) {
264 rem = (rem << SHIFT) + a->ob_digit[i];
265 z->ob_digit[i] = rem/n;
266 rem %= n;
267 }
268 *prem = rem;
269 return long_normalize(z);
270}
271
272/* Convert a long int object to a string, using a given conversion base.
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000273 Return a string object.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000274 If base is 8 or 16, add the proper prefix '0' or '0x'.
275 External linkage: used in bltinmodule.c by hex() and oct(). */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000276
Guido van Rossum234f9421993-06-17 12:35:49 +0000277static object *
Guido van Rossume32e0141992-01-19 16:31:05 +0000278long_format(aa, base)
279 object *aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000280 int base;
281{
Guido van Rossume32e0141992-01-19 16:31:05 +0000282 register longobject *a = (longobject *)aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000283 stringobject *str;
284 int i;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000285 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000286 char *p;
287 int bits;
288 char sign = '\0';
Guido van Rossume32e0141992-01-19 16:31:05 +0000289
290 if (a == NULL || !is_longobject(a)) {
291 err_badcall();
292 return NULL;
293 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000294 assert(base >= 2 && base <= 36);
295
296 /* Compute a rough upper bound for the length of the string */
297 i = base;
298 bits = 0;
299 while (i > 1) {
300 ++bits;
301 i >>= 1;
302 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000303 i = 6 + (size_a*SHIFT + bits-1) / bits;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000304 str = (stringobject *) newsizedstringobject((char *)0, i);
305 if (str == NULL)
306 return NULL;
307 p = GETSTRINGVALUE(str) + i;
308 *p = '\0';
Guido van Rossumc6913e71991-11-19 20:26:46 +0000309 *--p = 'L';
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000310 if (a->ob_size < 0)
311 sign = '-';
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000312
313 INCREF(a);
314 do {
315 digit rem;
316 longobject *temp = divrem1(a, (digit)base, &rem);
317 if (temp == NULL) {
318 DECREF(a);
319 DECREF(str);
320 return NULL;
321 }
322 if (rem < 10)
323 rem += '0';
324 else
325 rem += 'A'-10;
326 assert(p > GETSTRINGVALUE(str));
327 *--p = rem;
328 DECREF(a);
329 a = temp;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000330 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000331 DECREF(a);
332 DECREF(str);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000333 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000334 })
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000335 } while (ABS(a->ob_size) != 0);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000336 DECREF(a);
Guido van Rossum2c475421992-08-14 15:13:07 +0000337 if (base == 8) {
338 if (size_a != 0)
339 *--p = '0';
340 }
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000341 else if (base == 16) {
342 *--p = 'x';
343 *--p = '0';
344 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000345 else if (base != 10) {
346 *--p = '#';
347 *--p = '0' + base%10;
348 if (base > 10)
349 *--p = '0' + base/10;
350 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000351 if (sign)
352 *--p = sign;
353 if (p != GETSTRINGVALUE(str)) {
354 char *q = GETSTRINGVALUE(str);
355 assert(p > q);
356 do {
357 } while ((*q++ = *p++) != '\0');
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000358 q--;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000359 resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
360 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000361 return (object *)str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000362}
363
Guido van Rossum3535f6e1995-01-17 16:34:13 +0000364#if 0
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000365/* Convert a string to a long int object, in a given base.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000366 Base zero implies a default depending on the number.
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000367 External linkage: used in compile.c and stropmodule.c. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000368
369object *
370long_scan(str, base)
371 char *str;
372 int base;
373{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000374 return long_escan(str, (char **)NULL, base);
375}
Guido van Rossum3535f6e1995-01-17 16:34:13 +0000376#endif
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000377
378object *
379long_escan(str, pend, base)
380 char *str;
381 char **pend;
382 int base;
383{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000384 int sign = 1;
385 longobject *z;
386
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000387 if (base != 0 && base < 2 || base > 36) {
388 err_setstr(ValueError, "invalid base for long literal");
389 return NULL;
390 }
Guido van Rossum9fa2c111995-02-10 17:00:37 +0000391 while (*str != '\0' && isspace(Py_CHARMASK(*str)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000392 str++;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000393 if (*str == '+')
394 ++str;
395 else if (*str == '-') {
396 ++str;
397 sign = -1;
398 }
Guido van Rossum9fa2c111995-02-10 17:00:37 +0000399 while (*str != '\0' && isspace(Py_CHARMASK(*str)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000400 str++;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000401 if (base == 0) {
402 if (str[0] != '0')
403 base = 10;
404 else if (str[1] == 'x' || str[1] == 'X')
405 base = 16;
406 else
407 base = 8;
408 }
409 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
410 str += 2;
411 z = alloclongobject(0);
412 for ( ; z != NULL; ++str) {
413 int k = -1;
414 longobject *temp;
415
416 if (*str <= '9')
417 k = *str - '0';
418 else if (*str >= 'a')
419 k = *str - 'a' + 10;
420 else if (*str >= 'A')
421 k = *str - 'A' + 10;
422 if (k < 0 || k >= base)
423 break;
424 temp = muladd1(z, (digit)base, (digit)k);
425 DECREF(z);
426 z = temp;
427 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000428 if (sign < 0 && z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000429 z->ob_size = -(z->ob_size);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000430 if (pend)
431 *pend = str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000432 return (object *) z;
433}
434
435static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
Guido van Rossumc6913e71991-11-19 20:26:46 +0000436static object *long_pos PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000437static long_divrem PROTO((longobject *, longobject *,
438 longobject **, longobject **));
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000439
440/* Long division with remainder, top-level routine */
441
Guido van Rossume32e0141992-01-19 16:31:05 +0000442static int
443long_divrem(a, b, pdiv, prem)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000444 longobject *a, *b;
Guido van Rossume32e0141992-01-19 16:31:05 +0000445 longobject **pdiv;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000446 longobject **prem;
447{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000448 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000449 longobject *z;
450
451 if (size_b == 0) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000452 err_setstr(ZeroDivisionError, "long division or modulo");
453 return -1;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000454 }
455 if (size_a < size_b ||
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000456 size_a == size_b &&
457 a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000458 /* |a| < |b|. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000459 *pdiv = alloclongobject(0);
460 INCREF(a);
461 *prem = (longobject *) a;
462 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000463 }
464 if (size_b == 1) {
465 digit rem = 0;
466 z = divrem1(a, b->ob_digit[0], &rem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000467 if (z == NULL)
468 return -1;
469 *prem = (longobject *) newlongobject((long)rem);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000470 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000471 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000472 z = x_divrem(a, b, prem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000473 if (z == NULL)
474 return -1;
475 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000476 /* Set the signs.
477 The quotient z has the sign of a*b;
478 the remainder r has the sign of a,
479 so a = b*z + r. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000480 if ((a->ob_size < 0) != (b->ob_size < 0))
481 z->ob_size = -(z->ob_size);
482 if (a->ob_size < 0 && (*prem)->ob_size != 0)
483 (*prem)->ob_size = -((*prem)->ob_size);
484 *pdiv = z;
485 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000486}
487
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000488/* Unsigned long division with remainder -- the algorithm */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000489
490static longobject *
491x_divrem(v1, w1, prem)
492 longobject *v1, *w1;
493 longobject **prem;
494{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000495 int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000496 digit d = (twodigits)BASE / (w1->ob_digit[size_w-1] + 1);
497 longobject *v = mul1(v1, d);
498 longobject *w = mul1(w1, d);
499 longobject *a;
500 int j, k;
501
502 if (v == NULL || w == NULL) {
503 XDECREF(v);
504 XDECREF(w);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000505 return NULL;
506 }
507
508 assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000509 assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000510 assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000511
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000512 size_v = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000513 a = alloclongobject(size_v - size_w + 1);
514
515 for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
516 digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
517 twodigits q;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000518 stwodigits carry = 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000519 int i;
520
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000521 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000522 DECREF(a);
523 a = NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000524 break;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000525 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000526 if (vj == w->ob_digit[size_w-1])
527 q = MASK;
528 else
529 q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
530 w->ob_digit[size_w-1];
531
532 while (w->ob_digit[size_w-2]*q >
533 ((
534 ((twodigits)vj << SHIFT)
535 + v->ob_digit[j-1]
536 - q*w->ob_digit[size_w-1]
537 ) << SHIFT)
538 + v->ob_digit[j-2])
539 --q;
540
541 for (i = 0; i < size_w && i+k < size_v; ++i) {
542 twodigits z = w->ob_digit[i] * q;
543 digit zz = z >> SHIFT;
544 carry += v->ob_digit[i+k] - z + ((twodigits)zz << SHIFT);
545 v->ob_digit[i+k] = carry & MASK;
546 carry = (carry >> SHIFT) - zz;
547 }
548
549 if (i+k < size_v) {
550 carry += v->ob_digit[i+k];
551 v->ob_digit[i+k] = 0;
552 }
553
554 if (carry == 0)
555 a->ob_digit[k] = q;
556 else {
557 assert(carry == -1);
558 a->ob_digit[k] = q-1;
559 carry = 0;
560 for (i = 0; i < size_w && i+k < size_v; ++i) {
561 carry += v->ob_digit[i+k] + w->ob_digit[i];
562 v->ob_digit[i+k] = carry & MASK;
563 carry >>= SHIFT;
564 }
565 }
566 } /* for j, k */
567
Guido van Rossumc206c761995-01-10 15:23:19 +0000568 if (a == NULL)
569 *prem = NULL;
570 else {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000571 a = long_normalize(a);
Guido van Rossume32e0141992-01-19 16:31:05 +0000572 *prem = divrem1(v, d, &d);
573 /* d receives the (unused) remainder */
574 if (*prem == NULL) {
575 DECREF(a);
576 a = NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000577 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000578 }
579 DECREF(v);
580 DECREF(w);
581 return a;
582}
583
584/* Methods */
585
Guido van Rossume32e0141992-01-19 16:31:05 +0000586/* Forward */
Guido van Rossum8b27d921992-03-27 17:27:05 +0000587static void long_dealloc PROTO((object *));
Guido van Rossum8b27d921992-03-27 17:27:05 +0000588static object *long_repr PROTO((object *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000589static int long_compare PROTO((longobject *, longobject *));
Guido van Rossum9bfef441993-03-29 10:43:31 +0000590static long long_hash PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000591
592static object *long_add PROTO((longobject *, longobject *));
593static object *long_sub PROTO((longobject *, longobject *));
594static object *long_mul PROTO((longobject *, longobject *));
595static object *long_div PROTO((longobject *, longobject *));
596static object *long_mod PROTO((longobject *, longobject *));
597static object *long_divmod PROTO((longobject *, longobject *));
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000598static object *long_pow PROTO((longobject *, longobject *, longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000599static object *long_neg PROTO((longobject *));
600static object *long_pos PROTO((longobject *));
601static object *long_abs PROTO((longobject *));
602static int long_nonzero PROTO((longobject *));
603static object *long_invert PROTO((longobject *));
604static object *long_lshift PROTO((longobject *, longobject *));
605static object *long_rshift PROTO((longobject *, longobject *));
606static object *long_and PROTO((longobject *, longobject *));
607static object *long_xor PROTO((longobject *, longobject *));
608static object *long_or PROTO((longobject *, longobject *));
609
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000610static void
611long_dealloc(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000612 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000613{
614 DEL(v);
615}
616
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000617static object *
618long_repr(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000619 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000620{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000621 return long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000622}
623
624static int
625long_compare(a, b)
626 longobject *a, *b;
627{
628 int sign;
629
Guido van Rossumc6913e71991-11-19 20:26:46 +0000630 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000631 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000632 sign = 0;
633 else
634 sign = a->ob_size - b->ob_size;
635 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000636 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000637 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000638 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
639 ;
640 if (i < 0)
641 sign = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000642 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000643 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000644 if (a->ob_size < 0)
645 sign = -sign;
646 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000647 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000648 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000649}
650
Guido van Rossum9bfef441993-03-29 10:43:31 +0000651static long
652long_hash(v)
653 longobject *v;
654{
655 long x;
656 int i, sign;
657
658 /* This is designed so that Python ints and longs with the
659 same value hash to the same value, otherwise comparisons
660 of mapping keys will turn out weird */
661 i = v->ob_size;
662 sign = 1;
663 x = 0;
664 if (i < 0) {
665 sign = -1;
666 i = -(i);
667 }
668 while (--i >= 0) {
669 /* Force a 32-bit circular shift */
670 x = ((x << SHIFT) & ~MASK) | ((x >> (32-SHIFT)) & MASK);
671 x += v->ob_digit[i];
672 }
673 x = x * sign;
674 if (x == -1)
675 x = -2;
676 return x;
677}
678
679
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000680/* Add the absolute values of two long integers. */
681
682static longobject *x_add PROTO((longobject *, longobject *));
683static longobject *
684x_add(a, b)
685 longobject *a, *b;
686{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000687 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000688 longobject *z;
689 int i;
690 digit carry = 0;
691
692 /* Ensure a is the larger of the two: */
693 if (size_a < size_b) {
694 { longobject *temp = a; a = b; b = temp; }
695 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
696 }
697 z = alloclongobject(size_a+1);
698 if (z == NULL)
699 return NULL;
700 for (i = 0; i < size_b; ++i) {
701 carry += a->ob_digit[i] + b->ob_digit[i];
702 z->ob_digit[i] = carry & MASK;
703 /* The following assumes unsigned shifts don't
704 propagate the sign bit. */
705 carry >>= SHIFT;
706 }
707 for (; i < size_a; ++i) {
708 carry += a->ob_digit[i];
709 z->ob_digit[i] = carry & MASK;
710 carry >>= SHIFT;
711 }
712 z->ob_digit[i] = carry;
713 return long_normalize(z);
714}
715
716/* Subtract the absolute values of two integers. */
717
718static longobject *x_sub PROTO((longobject *, longobject *));
719static longobject *
720x_sub(a, b)
721 longobject *a, *b;
722{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000723 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000724 longobject *z;
725 int i;
726 int sign = 1;
727 digit borrow = 0;
728
729 /* Ensure a is the larger of the two: */
730 if (size_a < size_b) {
731 sign = -1;
732 { longobject *temp = a; a = b; b = temp; }
733 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
734 }
735 else if (size_a == size_b) {
736 /* Find highest digit where a and b differ: */
737 i = size_a;
738 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
739 ;
740 if (i < 0)
741 return alloclongobject(0);
742 if (a->ob_digit[i] < b->ob_digit[i]) {
743 sign = -1;
744 { longobject *temp = a; a = b; b = temp; }
745 }
746 size_a = size_b = i+1;
747 }
748 z = alloclongobject(size_a);
749 if (z == NULL)
750 return NULL;
751 for (i = 0; i < size_b; ++i) {
752 /* The following assumes unsigned arithmetic
753 works module 2**N for some N>SHIFT. */
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000754 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000755 z->ob_digit[i] = borrow & MASK;
756 borrow >>= SHIFT;
757 borrow &= 1; /* Keep only one sign bit */
758 }
759 for (; i < size_a; ++i) {
760 borrow = a->ob_digit[i] - borrow;
761 z->ob_digit[i] = borrow & MASK;
762 borrow >>= SHIFT;
763 }
764 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000765 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000766 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000767 return long_normalize(z);
768}
769
770static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000771long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000772 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000773 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000774{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000775 longobject *z;
776
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000777 if (a->ob_size < 0) {
778 if (b->ob_size < 0) {
779 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000780 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000781 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000782 }
783 else
784 z = x_sub(b, a);
785 }
786 else {
787 if (b->ob_size < 0)
788 z = x_sub(a, b);
789 else
790 z = x_add(a, b);
791 }
792 return (object *)z;
793}
794
795static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000796long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000797 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000798 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000799{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000800 longobject *z;
801
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000802 if (a->ob_size < 0) {
803 if (b->ob_size < 0)
804 z = x_sub(a, b);
805 else
806 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000807 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000808 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000809 }
810 else {
811 if (b->ob_size < 0)
812 z = x_add(a, b);
813 else
814 z = x_sub(a, b);
815 }
816 return (object *)z;
817}
818
819static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000820long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000821 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000822 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000823{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000824 int size_a;
825 int size_b;
826 longobject *z;
827 int i;
828
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000829 size_a = ABS(a->ob_size);
830 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000831 z = alloclongobject(size_a + size_b);
832 if (z == NULL)
833 return NULL;
834 for (i = 0; i < z->ob_size; ++i)
835 z->ob_digit[i] = 0;
836 for (i = 0; i < size_a; ++i) {
837 twodigits carry = 0;
838 twodigits f = a->ob_digit[i];
839 int j;
840
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000841 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000842 DECREF(z);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000843 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000844 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000845 for (j = 0; j < size_b; ++j) {
846 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
847 z->ob_digit[i+j] = carry & MASK;
848 carry >>= SHIFT;
849 }
850 for (; carry != 0; ++j) {
851 assert(i+j < z->ob_size);
852 carry += z->ob_digit[i+j];
853 z->ob_digit[i+j] = carry & MASK;
854 carry >>= SHIFT;
855 }
856 }
857 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000858 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000859 if (b->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000860 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000861 return (object *) long_normalize(z);
862}
863
Guido van Rossume32e0141992-01-19 16:31:05 +0000864/* The / and % operators are now defined in terms of divmod().
865 The expression a mod b has the value a - b*floor(a/b).
866 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000867 |a| by |b|, with the sign of a. This is also expressed
868 as a - b*trunc(a/b), if trunc truncates towards zero.
869 Some examples:
870 a b a rem b a mod b
871 13 10 3 3
872 -13 10 -3 7
873 13 -10 3 -7
874 -13 -10 -3 -3
875 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000876 have different signs. We then subtract one from the 'div'
877 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000878
Guido van Rossume32e0141992-01-19 16:31:05 +0000879static int l_divmod PROTO((longobject *, longobject *,
880 longobject **, longobject **));
881static int
882l_divmod(v, w, pdiv, pmod)
883 longobject *v;
884 longobject *w;
885 longobject **pdiv;
886 longobject **pmod;
887{
888 longobject *div, *mod;
889
890 if (long_divrem(v, w, &div, &mod) < 0)
891 return -1;
892 if (mod->ob_size < 0 && w->ob_size > 0 ||
893 mod->ob_size > 0 && w->ob_size < 0) {
894 longobject *temp;
895 longobject *one;
896 temp = (longobject *) long_add(mod, w);
897 DECREF(mod);
898 mod = temp;
899 if (mod == NULL) {
900 DECREF(div);
901 return -1;
902 }
903 one = (longobject *) newlongobject(1L);
904 if (one == NULL ||
905 (temp = (longobject *) long_sub(div, one)) == NULL) {
906 DECREF(mod);
907 DECREF(div);
Guido van Rossume5372401993-03-16 12:15:04 +0000908 XDECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000909 return -1;
910 }
Guido van Rossume5372401993-03-16 12:15:04 +0000911 DECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000912 DECREF(div);
913 div = temp;
914 }
915 *pdiv = div;
916 *pmod = mod;
917 return 0;
918}
919
920static object *
921long_div(v, w)
922 longobject *v;
923 longobject *w;
924{
925 longobject *div, *mod;
926 if (l_divmod(v, w, &div, &mod) < 0)
927 return NULL;
928 DECREF(mod);
929 return (object *)div;
930}
931
932static object *
933long_mod(v, w)
934 longobject *v;
935 longobject *w;
936{
937 longobject *div, *mod;
938 if (l_divmod(v, w, &div, &mod) < 0)
939 return NULL;
940 DECREF(div);
941 return (object *)mod;
942}
943
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000944static object *
945long_divmod(v, w)
946 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000947 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000948{
949 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000950 longobject *div, *mod;
951 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000952 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000953 z = newtupleobject(2);
954 if (z != NULL) {
955 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000956 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000957 }
958 else {
959 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000960 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000961 }
962 return z;
963}
964
965static object *
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000966long_pow(a, b, c)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000967 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000968 longobject *b;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000969 longobject *c;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000970{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000971 longobject *z, *div, *mod;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000972 int size_b, i;
973
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000974 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000975 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000976 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000977 return NULL;
978 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000979 z = (longobject *)newlongobject(1L);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000980 INCREF(a);
981 for (i = 0; i < size_b; ++i) {
982 digit bi = b->ob_digit[i];
983 int j;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000984
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000985 for (j = 0; j < SHIFT; ++j) {
986 longobject *temp;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000987
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000988 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000989 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000990 DECREF(z);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000991 if ((object*)c!=None && temp!=NULL) {
992 l_divmod(temp, c, &div, &mod);
993 XDECREF(div);
994 DECREF(temp);
995 temp = mod;
996 }
997 z = temp;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000998 if (z == NULL)
999 break;
1000 }
1001 bi >>= 1;
1002 if (bi == 0 && i+1 == size_b)
1003 break;
Guido van Rossume32e0141992-01-19 16:31:05 +00001004 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001005 DECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001006 if ((object*)c!=None && temp!=NULL) {
1007 l_divmod(temp, c, &div, &mod);
1008 XDECREF(div);
1009 DECREF(temp);
1010 temp = mod;
1011 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001012 a = temp;
1013 if (a == NULL) {
1014 DECREF(z);
1015 z = NULL;
1016 break;
1017 }
1018 }
Guido van Rossumc206c761995-01-10 15:23:19 +00001019 if (a == NULL || z == NULL)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001020 break;
1021 }
1022 XDECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001023 if ((object*)c!=None && z!=NULL) {
1024 l_divmod(z, c, &div, &mod);
1025 XDECREF(div);
1026 DECREF(z);
1027 z=mod;
1028 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001029 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001030}
1031
1032static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001033long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001034 longobject *v;
1035{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001036 /* Implement ~x as -(x+1) */
1037 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +00001038 longobject *w;
1039 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001040 if (w == NULL)
1041 return NULL;
1042 x = (longobject *) long_add(v, w);
1043 DECREF(w);
1044 if (x == NULL)
1045 return NULL;
1046 if (x->ob_size != 0)
1047 x->ob_size = -(x->ob_size);
1048 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001049}
1050
1051static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001052long_pos(v)
1053 longobject *v;
1054{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001055 INCREF(v);
1056 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001057}
1058
1059static object *
1060long_neg(v)
1061 longobject *v;
1062{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001063 longobject *z;
1064 int i, n;
1065 n = ABS(v->ob_size);
1066 if (n == 0) {
1067 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001068 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001069 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001070 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001071 z = alloclongobject(ABS(n));
1072 if (z == NULL)
1073 return NULL;
1074 for (i = 0; i < n; i++)
1075 z->ob_digit[i] = v->ob_digit[i];
1076 z->ob_size = -(v->ob_size);
1077 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001078}
1079
1080static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001081long_abs(v)
1082 longobject *v;
1083{
1084 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001085 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001086 else {
1087 INCREF(v);
1088 return (object *)v;
1089 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001090}
1091
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001092static int
1093long_nonzero(v)
1094 longobject *v;
1095{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001096 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001097}
1098
1099static object *
1100long_rshift(a, b)
1101 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001102 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001103{
1104 longobject *z;
1105 long shiftby;
1106 int newsize, wordshift, loshift, hishift, i, j;
1107 digit lomask, himask;
1108
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001109 if (a->ob_size < 0) {
1110 /* Right shifting negative numbers is harder */
1111 longobject *a1, *a2, *a3;
1112 a1 = (longobject *) long_invert(a);
1113 if (a1 == NULL) return NULL;
1114 a2 = (longobject *) long_rshift(a1, b);
1115 DECREF(a1);
1116 if (a2 == NULL) return NULL;
1117 a3 = (longobject *) long_invert(a2);
1118 DECREF(a2);
1119 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001120 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001121
1122 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001123 if (shiftby == -1L && err_occurred())
1124 return NULL;
1125 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001126 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001127 return NULL;
1128 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001129 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001130 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001131 if (newsize <= 0) {
1132 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001133 return (object *)z;
1134 }
1135 loshift = shiftby % SHIFT;
1136 hishift = SHIFT - loshift;
1137 lomask = ((digit)1 << hishift) - 1;
1138 himask = MASK ^ lomask;
1139 z = alloclongobject(newsize);
1140 if (z == NULL)
1141 return NULL;
1142 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001143 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001144 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1145 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1146 if (i+1 < newsize)
1147 z->ob_digit[i] |=
1148 (a->ob_digit[j+1] << hishift) & himask;
1149 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001150 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001151}
1152
1153static object *
1154long_lshift(a, b)
1155 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001156 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001157{
1158 longobject *z;
1159 long shiftby;
1160 int newsize, wordshift, loshift, hishift, i, j;
1161 digit lomask, himask;
1162
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001163 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001164 if (shiftby == -1L && err_occurred())
1165 return NULL;
1166 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001167 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001168 return NULL;
1169 }
1170 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001171 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001172 return NULL;
1173 }
1174 if (shiftby % SHIFT == 0) {
1175 wordshift = shiftby / SHIFT;
1176 loshift = 0;
1177 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001178 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001179 lomask = MASK;
1180 himask = 0;
1181 }
1182 else {
1183 wordshift = shiftby / SHIFT + 1;
1184 loshift = SHIFT - shiftby%SHIFT;
1185 hishift = shiftby % SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001186 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001187 lomask = ((digit)1 << hishift) - 1;
1188 himask = MASK ^ lomask;
1189 }
1190 z = alloclongobject(newsize);
1191 if (z == NULL)
1192 return NULL;
1193 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001194 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001195 for (i = 0; i < wordshift; i++)
1196 z->ob_digit[i] = 0;
1197 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1198 if (i > 0)
1199 z->ob_digit[i-1] |=
1200 (a->ob_digit[j] << hishift) & himask;
1201 z->ob_digit[i] =
1202 (a->ob_digit[j] >> loshift) & lomask;
1203 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001204 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001205}
1206
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001207
1208/* Bitwise and/xor/or operations */
1209
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001210#define MAX(x, y) ((x) < (y) ? (y) : (x))
1211#define MIN(x, y) ((x) > (y) ? (y) : (x))
1212
Guido van Rossume32e0141992-01-19 16:31:05 +00001213static object *long_bitwise PROTO((longobject *, int, longobject *));
1214static object *
1215long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001216 longobject *a;
1217 int op; /* '&', '|', '^' */
1218 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001219{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001220 digit maska, maskb; /* 0 or MASK */
1221 int negz;
1222 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001223 longobject *z;
1224 int i;
Guido van Rossum8b27d921992-03-27 17:27:05 +00001225 digit diga, digb;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001226 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001227
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001228 if (a->ob_size < 0) {
1229 a = (longobject *) long_invert(a);
1230 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001231 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001232 else {
1233 INCREF(a);
1234 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001235 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001236 if (b->ob_size < 0) {
1237 b = (longobject *) long_invert(b);
1238 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001239 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001240 else {
1241 INCREF(b);
1242 maskb = 0;
1243 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001244
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001245 size_a = a->ob_size;
1246 size_b = b->ob_size;
1247 size_z = MAX(size_a, size_b);
1248 z = alloclongobject(size_z);
1249 if (a == NULL || b == NULL || z == NULL) {
1250 XDECREF(a);
1251 XDECREF(b);
1252 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001253 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001254 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001255
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001256 negz = 0;
1257 switch (op) {
1258 case '^':
1259 if (maska != maskb) {
1260 maska ^= MASK;
1261 negz = -1;
1262 }
1263 break;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001264 case '&':
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001265 if (maska && maskb) {
1266 op = '|';
1267 maska ^= MASK;
1268 maskb ^= MASK;
1269 negz = -1;
1270 }
1271 break;
1272 case '|':
1273 if (maska || maskb) {
1274 op = '&';
1275 maska ^= MASK;
1276 maskb ^= MASK;
1277 negz = -1;
1278 }
1279 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001280 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001281
1282 for (i = 0; i < size_z; ++i) {
1283 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1284 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1285 switch (op) {
1286 case '&': z->ob_digit[i] = diga & digb; break;
1287 case '|': z->ob_digit[i] = diga | digb; break;
1288 case '^': z->ob_digit[i] = diga ^ digb; break;
1289 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001290 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001291
1292 DECREF(a);
1293 DECREF(b);
1294 z = long_normalize(z);
1295 if (negz == 0)
1296 return (object *) z;
1297 v = long_invert(z);
1298 DECREF(z);
1299 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001300}
1301
Guido van Rossumc6913e71991-11-19 20:26:46 +00001302static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001303long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001304 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001305 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001306{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001307 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001308}
1309
1310static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001311long_xor(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001312 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001313 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001314{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001315 return long_bitwise(a, '^', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001316}
1317
1318static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001319long_or(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001320 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001321 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001322{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001323 return long_bitwise(a, '|', b);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001324}
1325
Guido van Rossum234f9421993-06-17 12:35:49 +00001326static int
Guido van Rossume6eefc21992-08-14 12:06:52 +00001327long_coerce(pv, pw)
1328 object **pv;
1329 object **pw;
1330{
1331 if (is_intobject(*pw)) {
1332 *pw = newlongobject(getintvalue(*pw));
1333 INCREF(*pv);
1334 return 0;
1335 }
1336 return 1; /* Can't do it */
1337}
1338
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001339static object *
1340long_int(v)
1341 object *v;
1342{
1343 long x;
1344 x = getlongvalue(v);
1345 if (err_occurred())
1346 return NULL;
1347 return newintobject(x);
1348}
1349
1350static object *
1351long_long(v)
1352 object *v;
1353{
1354 INCREF(v);
1355 return v;
1356}
1357
1358static object *
1359long_float(v)
1360 object *v;
1361{
1362 return newfloatobject(dgetlongvalue(v));
1363}
1364
1365static object *
1366long_oct(v)
1367 object *v;
1368{
1369 return long_format(v, 8);
1370}
1371
1372static object *
1373long_hex(v)
1374 object *v;
1375{
1376 return long_format(v, 16);
1377}
1378
1379
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001380#define UF (unaryfunc)
1381#define BF (binaryfunc)
1382#define TF (ternaryfunc)
1383#define IF (inquiry)
Guido van Rossum8b27d921992-03-27 17:27:05 +00001384
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001385static number_methods long_as_number = {
Guido van Rossum8b27d921992-03-27 17:27:05 +00001386 BF long_add, /*nb_add*/
1387 BF long_sub, /*nb_subtract*/
1388 BF long_mul, /*nb_multiply*/
1389 BF long_div, /*nb_divide*/
1390 BF long_mod, /*nb_remainder*/
1391 BF long_divmod, /*nb_divmod*/
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001392 TF long_pow, /*nb_power*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001393 UF long_neg, /*nb_negative*/
1394 UF long_pos, /*tp_positive*/
1395 UF long_abs, /*tp_absolute*/
1396 IF long_nonzero,/*tp_nonzero*/
1397 UF long_invert, /*nb_invert*/
1398 BF long_lshift, /*nb_lshift*/
1399 BF long_rshift, /*nb_rshift*/
1400 BF long_and, /*nb_and*/
1401 BF long_xor, /*nb_xor*/
1402 BF long_or, /*nb_or*/
Guido van Rossume6eefc21992-08-14 12:06:52 +00001403 (int (*) FPROTO((object **, object **)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001404 (coercion)long_coerce, /*nb_coerce*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001405 UF long_int, /*nb_int*/
1406 UF long_long, /*nb_long*/
1407 UF long_float, /*nb_float*/
1408 UF long_oct, /*nb_oct*/
1409 UF long_hex, /*nb_hex*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001410};
1411
1412typeobject Longtype = {
1413 OB_HEAD_INIT(&Typetype)
1414 0,
1415 "long int",
1416 sizeof(longobject) - sizeof(digit),
1417 sizeof(digit),
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001418 (destructor)long_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001419 0, /*tp_print*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001420 0, /*tp_getattr*/
1421 0, /*tp_setattr*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001422 (int (*) FPROTO((object *, object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001423 (cmpfunc)long_compare, /*tp_compare*/
1424 (reprfunc)long_repr, /*tp_repr*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001425 &long_as_number,/*tp_as_number*/
1426 0, /*tp_as_sequence*/
1427 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +00001428 (long (*) FPROTO((object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001429 (hashfunc)long_hash, /*tp_hash*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001430};