blob: 1ec4511a708393545f51cf6d60bcb0faefb6069e [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
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Long (arbitrary precision) integer object implementation */
26
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000027/* XXX The functional organization of this file is terrible */
28
Guido van Rossumedcc38a1991-05-05 20:09:44 +000029#include "allobjects.h"
30#include "longintrepr.h"
Guido van Rossum687ec181995-03-04 22:43:47 +000031#include "mymath.h"
Guido van Rossumedcc38a1991-05-05 20:09:44 +000032#include <assert.h>
Guido van Rossumeb1fafc1994-08-29 12:47:19 +000033#include <ctype.h>
Guido van Rossumedcc38a1991-05-05 20:09:44 +000034
Guido van Rossume32e0141992-01-19 16:31:05 +000035#define ABS(x) ((x) < 0 ? -(x) : (x))
36
37/* Forward */
38static longobject *long_normalize PROTO((longobject *));
39static longobject *mul1 PROTO((longobject *, wdigit));
40static longobject *muladd1 PROTO((longobject *, wdigit, wdigit));
41static longobject *divrem1 PROTO((longobject *, wdigit, digit *));
Guido van Rossumb73cc041993-11-01 16:28:59 +000042static object *long_format PROTO((object *aa, int base));
Guido van Rossume32e0141992-01-19 16:31:05 +000043
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000044static int ticker; /* XXX Could be shared with ceval? */
45
Guido van Rossumeb1fafc1994-08-29 12:47:19 +000046#define SIGCHECK(block) \
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000047 if (--ticker < 0) { \
48 ticker = 100; \
Guido van Rossumeb1fafc1994-08-29 12:47:19 +000049 if (sigcheck()) { block; } \
Guido van Rossum23d6f0e1991-05-14 12:06:49 +000050 }
51
Guido van Rossumedcc38a1991-05-05 20:09:44 +000052/* Normalize (remove leading zeros from) a long int object.
53 Doesn't attempt to free the storage--in most cases, due to the nature
54 of the algorithms used, this could save at most be one word anyway. */
55
Guido van Rossum4c260ff1992-01-14 18:36:43 +000056static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +000057long_normalize(v)
58 register longobject *v;
59{
Guido van Rossum4c260ff1992-01-14 18:36:43 +000060 int j = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +000061 register int i = j;
62
63 while (i > 0 && v->ob_digit[i-1] == 0)
64 --i;
65 if (i != j)
Guido van Rossum4c260ff1992-01-14 18:36:43 +000066 v->ob_size = (v->ob_size < 0) ? -(i) : i;
Guido van Rossumedcc38a1991-05-05 20:09:44 +000067 return v;
68}
69
70/* Allocate a new long int object with size digits.
71 Return NULL and set exception if we run out of memory. */
72
73longobject *
74alloclongobject(size)
75 int size;
76{
77 return NEWVAROBJ(longobject, &Longtype, size);
78}
79
80/* Create a new long int object from a C long int */
81
82object *
83newlongobject(ival)
84 long ival;
85{
86 /* Assume a C long fits in at most 3 'digits' */
Guido van Rossumeb1fafc1994-08-29 12:47:19 +000087 /* XXX On 64 bit machines this isn't true!!! */
Guido van Rossumedcc38a1991-05-05 20:09:44 +000088 longobject *v = alloclongobject(3);
89 if (v != NULL) {
90 if (ival < 0) {
91 ival = -ival;
Guido van Rossum4c260ff1992-01-14 18:36:43 +000092 v->ob_size = -(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +000093 }
94 v->ob_digit[0] = ival & MASK;
95 v->ob_digit[1] = (ival >> SHIFT) & MASK;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +000096 v->ob_digit[2] = ((unsigned long)ival >> (2*SHIFT)) & MASK;
Guido van Rossumedcc38a1991-05-05 20:09:44 +000097 v = long_normalize(v);
98 }
99 return (object *)v;
100}
101
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000102/* Create a new long int object from a C double */
103
104object *
Guido van Rossum687ec181995-03-04 22:43:47 +0000105#ifdef MPW
106dnewlongobject(double dval)
107#else
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000108dnewlongobject(dval)
109 double dval;
Guido van Rossum687ec181995-03-04 22:43:47 +0000110#endif /* MPW */
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000111{
112 longobject *v;
113 double frac;
114 int i, ndig, expo, neg;
115 neg = 0;
116 if (dval < 0.0) {
117 neg = 1;
118 dval = -dval;
119 }
120 frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
121 if (expo <= 0)
122 return newlongobject(0L);
123 ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
124 v = alloclongobject(ndig);
125 if (v == NULL)
126 return NULL;
127 frac = ldexp(frac, (expo-1) % SHIFT + 1);
128 for (i = ndig; --i >= 0; ) {
129 long bits = (long)frac;
130 v->ob_digit[i] = bits;
131 frac = frac - (double)bits;
132 frac = ldexp(frac, SHIFT);
133 }
134 if (neg)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000135 v->ob_size = -(v->ob_size);
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000136 return (object *)v;
137}
138
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000139/* Get a C long int from a long int object.
140 Returns -1 and sets an error condition if overflow occurs. */
141
142long
143getlongvalue(vv)
144 object *vv;
145{
146 register longobject *v;
147 long x, prev;
148 int i, sign;
149
150 if (vv == NULL || !is_longobject(vv)) {
151 err_badcall();
152 return -1;
153 }
154 v = (longobject *)vv;
155 i = v->ob_size;
156 sign = 1;
157 x = 0;
158 if (i < 0) {
159 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000160 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000161 }
162 while (--i >= 0) {
163 prev = x;
164 x = (x << SHIFT) + v->ob_digit[i];
165 if ((x >> SHIFT) != prev) {
Guido van Rossum03093a21994-09-28 15:51:32 +0000166 err_setstr(OverflowError,
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000167 "long int too long to convert");
168 return -1;
169 }
170 }
171 return x * sign;
172}
173
174/* Get a C double from a long int object. No overflow check. */
175
176double
177dgetlongvalue(vv)
178 object *vv;
179{
180 register longobject *v;
181 double x;
182 double multiplier = (double) (1L << SHIFT);
183 int i, sign;
184
185 if (vv == NULL || !is_longobject(vv)) {
186 err_badcall();
187 return -1;
188 }
189 v = (longobject *)vv;
190 i = v->ob_size;
191 sign = 1;
192 x = 0.0;
193 if (i < 0) {
194 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000195 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000196 }
197 while (--i >= 0) {
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000198 x = x*multiplier + (double)v->ob_digit[i];
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000199 }
200 return x * sign;
201}
202
203/* Multiply by a single digit, ignoring the sign. */
204
Guido van Rossume32e0141992-01-19 16:31:05 +0000205static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000206mul1(a, n)
207 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000208 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000209{
210 return muladd1(a, n, (digit)0);
211}
212
213/* Multiply by a single digit and add 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 +0000216muladd1(a, n, extra)
217 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000218 wdigit n;
219 wdigit extra;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000220{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000221 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000222 longobject *z = alloclongobject(size_a+1);
223 twodigits carry = extra;
224 int i;
225
226 if (z == NULL)
227 return NULL;
228 for (i = 0; i < size_a; ++i) {
229 carry += (twodigits)a->ob_digit[i] * n;
230 z->ob_digit[i] = carry & MASK;
231 carry >>= SHIFT;
232 }
233 z->ob_digit[i] = carry;
234 return long_normalize(z);
235}
236
237/* Divide a long integer by a digit, returning both the quotient
238 (as function result) and the remainder (through *prem).
239 The sign of a is ignored; n should not be zero. */
240
Guido van Rossume32e0141992-01-19 16:31:05 +0000241static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000242divrem1(a, n, prem)
243 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000244 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000245 digit *prem;
246{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000247 int size = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000248 longobject *z;
249 int i;
250 twodigits rem = 0;
251
252 assert(n > 0 && n <= MASK);
253 z = alloclongobject(size);
254 if (z == NULL)
255 return NULL;
256 for (i = size; --i >= 0; ) {
257 rem = (rem << SHIFT) + a->ob_digit[i];
258 z->ob_digit[i] = rem/n;
259 rem %= n;
260 }
261 *prem = rem;
262 return long_normalize(z);
263}
264
265/* Convert a long int object to a string, using a given conversion base.
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000266 Return a string object.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000267 If base is 8 or 16, add the proper prefix '0' or '0x'.
268 External linkage: used in bltinmodule.c by hex() and oct(). */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000269
Guido van Rossum234f9421993-06-17 12:35:49 +0000270static object *
Guido van Rossume32e0141992-01-19 16:31:05 +0000271long_format(aa, base)
272 object *aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000273 int base;
274{
Guido van Rossume32e0141992-01-19 16:31:05 +0000275 register longobject *a = (longobject *)aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000276 stringobject *str;
277 int i;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000278 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000279 char *p;
280 int bits;
281 char sign = '\0';
Guido van Rossume32e0141992-01-19 16:31:05 +0000282
283 if (a == NULL || !is_longobject(a)) {
284 err_badcall();
285 return NULL;
286 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000287 assert(base >= 2 && base <= 36);
288
289 /* Compute a rough upper bound for the length of the string */
290 i = base;
291 bits = 0;
292 while (i > 1) {
293 ++bits;
294 i >>= 1;
295 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000296 i = 6 + (size_a*SHIFT + bits-1) / bits;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000297 str = (stringobject *) newsizedstringobject((char *)0, i);
298 if (str == NULL)
299 return NULL;
300 p = GETSTRINGVALUE(str) + i;
301 *p = '\0';
Guido van Rossumc6913e71991-11-19 20:26:46 +0000302 *--p = 'L';
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000303 if (a->ob_size < 0)
304 sign = '-';
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000305
306 INCREF(a);
307 do {
308 digit rem;
309 longobject *temp = divrem1(a, (digit)base, &rem);
310 if (temp == NULL) {
311 DECREF(a);
312 DECREF(str);
313 return NULL;
314 }
315 if (rem < 10)
316 rem += '0';
317 else
318 rem += 'A'-10;
319 assert(p > GETSTRINGVALUE(str));
320 *--p = rem;
321 DECREF(a);
322 a = temp;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000323 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000324 DECREF(a);
325 DECREF(str);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000326 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000327 })
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000328 } while (ABS(a->ob_size) != 0);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000329 DECREF(a);
Guido van Rossum2c475421992-08-14 15:13:07 +0000330 if (base == 8) {
331 if (size_a != 0)
332 *--p = '0';
333 }
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000334 else if (base == 16) {
335 *--p = 'x';
336 *--p = '0';
337 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000338 else if (base != 10) {
339 *--p = '#';
340 *--p = '0' + base%10;
341 if (base > 10)
342 *--p = '0' + base/10;
343 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000344 if (sign)
345 *--p = sign;
346 if (p != GETSTRINGVALUE(str)) {
347 char *q = GETSTRINGVALUE(str);
348 assert(p > q);
349 do {
350 } while ((*q++ = *p++) != '\0');
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000351 q--;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000352 resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
353 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000354 return (object *)str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000355}
356
Guido van Rossum3535f6e1995-01-17 16:34:13 +0000357#if 0
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000358/* Convert a string to a long int object, in a given base.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000359 Base zero implies a default depending on the number.
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000360 External linkage: used in compile.c and stropmodule.c. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000361
362object *
363long_scan(str, base)
364 char *str;
365 int base;
366{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000367 return long_escan(str, (char **)NULL, base);
368}
Guido van Rossum3535f6e1995-01-17 16:34:13 +0000369#endif
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000370
371object *
372long_escan(str, pend, base)
373 char *str;
374 char **pend;
375 int base;
376{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000377 int sign = 1;
378 longobject *z;
379
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000380 if (base != 0 && base < 2 || base > 36) {
381 err_setstr(ValueError, "invalid base for long literal");
382 return NULL;
383 }
Guido van Rossum9fa2c111995-02-10 17:00:37 +0000384 while (*str != '\0' && isspace(Py_CHARMASK(*str)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000385 str++;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000386 if (*str == '+')
387 ++str;
388 else if (*str == '-') {
389 ++str;
390 sign = -1;
391 }
Guido van Rossum9fa2c111995-02-10 17:00:37 +0000392 while (*str != '\0' && isspace(Py_CHARMASK(*str)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000393 str++;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000394 if (base == 0) {
395 if (str[0] != '0')
396 base = 10;
397 else if (str[1] == 'x' || str[1] == 'X')
398 base = 16;
399 else
400 base = 8;
401 }
402 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
403 str += 2;
404 z = alloclongobject(0);
405 for ( ; z != NULL; ++str) {
406 int k = -1;
407 longobject *temp;
408
409 if (*str <= '9')
410 k = *str - '0';
411 else if (*str >= 'a')
412 k = *str - 'a' + 10;
413 else if (*str >= 'A')
414 k = *str - 'A' + 10;
415 if (k < 0 || k >= base)
416 break;
417 temp = muladd1(z, (digit)base, (digit)k);
418 DECREF(z);
419 z = temp;
420 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000421 if (sign < 0 && z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000422 z->ob_size = -(z->ob_size);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000423 if (pend)
424 *pend = str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000425 return (object *) z;
426}
427
428static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
Guido van Rossumc6913e71991-11-19 20:26:46 +0000429static object *long_pos PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000430static long_divrem PROTO((longobject *, longobject *,
431 longobject **, longobject **));
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000432
433/* Long division with remainder, top-level routine */
434
Guido van Rossume32e0141992-01-19 16:31:05 +0000435static int
436long_divrem(a, b, pdiv, prem)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000437 longobject *a, *b;
Guido van Rossume32e0141992-01-19 16:31:05 +0000438 longobject **pdiv;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000439 longobject **prem;
440{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000441 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000442 longobject *z;
443
444 if (size_b == 0) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000445 err_setstr(ZeroDivisionError, "long division or modulo");
446 return -1;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000447 }
448 if (size_a < size_b ||
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000449 size_a == size_b &&
450 a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000451 /* |a| < |b|. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000452 *pdiv = alloclongobject(0);
453 INCREF(a);
454 *prem = (longobject *) a;
455 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000456 }
457 if (size_b == 1) {
458 digit rem = 0;
459 z = divrem1(a, b->ob_digit[0], &rem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000460 if (z == NULL)
461 return -1;
462 *prem = (longobject *) newlongobject((long)rem);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000463 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000464 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000465 z = x_divrem(a, b, prem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000466 if (z == NULL)
467 return -1;
468 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000469 /* Set the signs.
470 The quotient z has the sign of a*b;
471 the remainder r has the sign of a,
472 so a = b*z + r. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000473 if ((a->ob_size < 0) != (b->ob_size < 0))
474 z->ob_size = -(z->ob_size);
475 if (a->ob_size < 0 && (*prem)->ob_size != 0)
476 (*prem)->ob_size = -((*prem)->ob_size);
477 *pdiv = z;
478 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000479}
480
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000481/* Unsigned long division with remainder -- the algorithm */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000482
483static longobject *
484x_divrem(v1, w1, prem)
485 longobject *v1, *w1;
486 longobject **prem;
487{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000488 int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000489 digit d = (twodigits)BASE / (w1->ob_digit[size_w-1] + 1);
490 longobject *v = mul1(v1, d);
491 longobject *w = mul1(w1, d);
492 longobject *a;
493 int j, k;
494
495 if (v == NULL || w == NULL) {
496 XDECREF(v);
497 XDECREF(w);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000498 return NULL;
499 }
500
501 assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000502 assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000503 assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000504
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000505 size_v = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000506 a = alloclongobject(size_v - size_w + 1);
507
508 for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
509 digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
510 twodigits q;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000511 stwodigits carry = 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000512 int i;
513
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000514 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000515 DECREF(a);
516 a = NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000517 break;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000518 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000519 if (vj == w->ob_digit[size_w-1])
520 q = MASK;
521 else
522 q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
523 w->ob_digit[size_w-1];
524
525 while (w->ob_digit[size_w-2]*q >
526 ((
527 ((twodigits)vj << SHIFT)
528 + v->ob_digit[j-1]
529 - q*w->ob_digit[size_w-1]
530 ) << SHIFT)
531 + v->ob_digit[j-2])
532 --q;
533
534 for (i = 0; i < size_w && i+k < size_v; ++i) {
535 twodigits z = w->ob_digit[i] * q;
536 digit zz = z >> SHIFT;
537 carry += v->ob_digit[i+k] - z + ((twodigits)zz << SHIFT);
538 v->ob_digit[i+k] = carry & MASK;
539 carry = (carry >> SHIFT) - zz;
540 }
541
542 if (i+k < size_v) {
543 carry += v->ob_digit[i+k];
544 v->ob_digit[i+k] = 0;
545 }
546
547 if (carry == 0)
548 a->ob_digit[k] = q;
549 else {
550 assert(carry == -1);
551 a->ob_digit[k] = q-1;
552 carry = 0;
553 for (i = 0; i < size_w && i+k < size_v; ++i) {
554 carry += v->ob_digit[i+k] + w->ob_digit[i];
555 v->ob_digit[i+k] = carry & MASK;
556 carry >>= SHIFT;
557 }
558 }
559 } /* for j, k */
560
Guido van Rossumc206c761995-01-10 15:23:19 +0000561 if (a == NULL)
562 *prem = NULL;
563 else {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000564 a = long_normalize(a);
Guido van Rossume32e0141992-01-19 16:31:05 +0000565 *prem = divrem1(v, d, &d);
566 /* d receives the (unused) remainder */
567 if (*prem == NULL) {
568 DECREF(a);
569 a = NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000570 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000571 }
572 DECREF(v);
573 DECREF(w);
574 return a;
575}
576
577/* Methods */
578
Guido van Rossume32e0141992-01-19 16:31:05 +0000579/* Forward */
Guido van Rossum8b27d921992-03-27 17:27:05 +0000580static void long_dealloc PROTO((object *));
Guido van Rossum8b27d921992-03-27 17:27:05 +0000581static object *long_repr PROTO((object *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000582static int long_compare PROTO((longobject *, longobject *));
Guido van Rossum9bfef441993-03-29 10:43:31 +0000583static long long_hash PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000584
585static object *long_add PROTO((longobject *, longobject *));
586static object *long_sub PROTO((longobject *, longobject *));
587static object *long_mul PROTO((longobject *, longobject *));
588static object *long_div PROTO((longobject *, longobject *));
589static object *long_mod PROTO((longobject *, longobject *));
590static object *long_divmod PROTO((longobject *, longobject *));
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000591static object *long_pow PROTO((longobject *, longobject *, longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000592static object *long_neg PROTO((longobject *));
593static object *long_pos PROTO((longobject *));
594static object *long_abs PROTO((longobject *));
595static int long_nonzero PROTO((longobject *));
596static object *long_invert PROTO((longobject *));
597static object *long_lshift PROTO((longobject *, longobject *));
598static object *long_rshift PROTO((longobject *, longobject *));
599static object *long_and PROTO((longobject *, longobject *));
600static object *long_xor PROTO((longobject *, longobject *));
601static object *long_or PROTO((longobject *, longobject *));
602
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000603static void
604long_dealloc(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000605 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000606{
607 DEL(v);
608}
609
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000610static object *
611long_repr(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000612 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000613{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000614 return long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000615}
616
617static int
618long_compare(a, b)
619 longobject *a, *b;
620{
621 int sign;
622
Guido van Rossumc6913e71991-11-19 20:26:46 +0000623 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000624 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000625 sign = 0;
626 else
627 sign = a->ob_size - b->ob_size;
628 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000629 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000630 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000631 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
632 ;
633 if (i < 0)
634 sign = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000635 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000636 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000637 if (a->ob_size < 0)
638 sign = -sign;
639 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000640 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000641 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000642}
643
Guido van Rossum9bfef441993-03-29 10:43:31 +0000644static long
645long_hash(v)
646 longobject *v;
647{
648 long x;
649 int i, sign;
650
651 /* This is designed so that Python ints and longs with the
652 same value hash to the same value, otherwise comparisons
653 of mapping keys will turn out weird */
654 i = v->ob_size;
655 sign = 1;
656 x = 0;
657 if (i < 0) {
658 sign = -1;
659 i = -(i);
660 }
661 while (--i >= 0) {
662 /* Force a 32-bit circular shift */
663 x = ((x << SHIFT) & ~MASK) | ((x >> (32-SHIFT)) & MASK);
664 x += v->ob_digit[i];
665 }
666 x = x * sign;
667 if (x == -1)
668 x = -2;
669 return x;
670}
671
672
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000673/* Add the absolute values of two long integers. */
674
675static longobject *x_add PROTO((longobject *, longobject *));
676static longobject *
677x_add(a, b)
678 longobject *a, *b;
679{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000680 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000681 longobject *z;
682 int i;
683 digit carry = 0;
684
685 /* Ensure a is the larger of the two: */
686 if (size_a < size_b) {
687 { longobject *temp = a; a = b; b = temp; }
688 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
689 }
690 z = alloclongobject(size_a+1);
691 if (z == NULL)
692 return NULL;
693 for (i = 0; i < size_b; ++i) {
694 carry += a->ob_digit[i] + b->ob_digit[i];
695 z->ob_digit[i] = carry & MASK;
696 /* The following assumes unsigned shifts don't
697 propagate the sign bit. */
698 carry >>= SHIFT;
699 }
700 for (; i < size_a; ++i) {
701 carry += a->ob_digit[i];
702 z->ob_digit[i] = carry & MASK;
703 carry >>= SHIFT;
704 }
705 z->ob_digit[i] = carry;
706 return long_normalize(z);
707}
708
709/* Subtract the absolute values of two integers. */
710
711static longobject *x_sub PROTO((longobject *, longobject *));
712static longobject *
713x_sub(a, b)
714 longobject *a, *b;
715{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000716 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000717 longobject *z;
718 int i;
719 int sign = 1;
720 digit borrow = 0;
721
722 /* Ensure a is the larger of the two: */
723 if (size_a < size_b) {
724 sign = -1;
725 { longobject *temp = a; a = b; b = temp; }
726 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
727 }
728 else if (size_a == size_b) {
729 /* Find highest digit where a and b differ: */
730 i = size_a;
731 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
732 ;
733 if (i < 0)
734 return alloclongobject(0);
735 if (a->ob_digit[i] < b->ob_digit[i]) {
736 sign = -1;
737 { longobject *temp = a; a = b; b = temp; }
738 }
739 size_a = size_b = i+1;
740 }
741 z = alloclongobject(size_a);
742 if (z == NULL)
743 return NULL;
744 for (i = 0; i < size_b; ++i) {
745 /* The following assumes unsigned arithmetic
746 works module 2**N for some N>SHIFT. */
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000747 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000748 z->ob_digit[i] = borrow & MASK;
749 borrow >>= SHIFT;
750 borrow &= 1; /* Keep only one sign bit */
751 }
752 for (; i < size_a; ++i) {
753 borrow = a->ob_digit[i] - borrow;
754 z->ob_digit[i] = borrow & MASK;
755 borrow >>= SHIFT;
756 }
757 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000758 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000759 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000760 return long_normalize(z);
761}
762
763static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000764long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000765 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000766 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000767{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000768 longobject *z;
769
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000770 if (a->ob_size < 0) {
771 if (b->ob_size < 0) {
772 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000773 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000774 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000775 }
776 else
777 z = x_sub(b, a);
778 }
779 else {
780 if (b->ob_size < 0)
781 z = x_sub(a, b);
782 else
783 z = x_add(a, b);
784 }
785 return (object *)z;
786}
787
788static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000789long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000790 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000791 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000792{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000793 longobject *z;
794
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000795 if (a->ob_size < 0) {
796 if (b->ob_size < 0)
797 z = x_sub(a, b);
798 else
799 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000800 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000801 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000802 }
803 else {
804 if (b->ob_size < 0)
805 z = x_add(a, b);
806 else
807 z = x_sub(a, b);
808 }
809 return (object *)z;
810}
811
812static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000813long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000814 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000815 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000816{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000817 int size_a;
818 int size_b;
819 longobject *z;
820 int i;
821
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000822 size_a = ABS(a->ob_size);
823 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000824 z = alloclongobject(size_a + size_b);
825 if (z == NULL)
826 return NULL;
827 for (i = 0; i < z->ob_size; ++i)
828 z->ob_digit[i] = 0;
829 for (i = 0; i < size_a; ++i) {
830 twodigits carry = 0;
831 twodigits f = a->ob_digit[i];
832 int j;
833
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000834 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000835 DECREF(z);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000836 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000837 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000838 for (j = 0; j < size_b; ++j) {
839 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
840 z->ob_digit[i+j] = carry & MASK;
841 carry >>= SHIFT;
842 }
843 for (; carry != 0; ++j) {
844 assert(i+j < z->ob_size);
845 carry += z->ob_digit[i+j];
846 z->ob_digit[i+j] = carry & MASK;
847 carry >>= SHIFT;
848 }
849 }
850 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000851 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000852 if (b->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000853 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000854 return (object *) long_normalize(z);
855}
856
Guido van Rossume32e0141992-01-19 16:31:05 +0000857/* The / and % operators are now defined in terms of divmod().
858 The expression a mod b has the value a - b*floor(a/b).
859 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000860 |a| by |b|, with the sign of a. This is also expressed
861 as a - b*trunc(a/b), if trunc truncates towards zero.
862 Some examples:
863 a b a rem b a mod b
864 13 10 3 3
865 -13 10 -3 7
866 13 -10 3 -7
867 -13 -10 -3 -3
868 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000869 have different signs. We then subtract one from the 'div'
870 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000871
Guido van Rossume32e0141992-01-19 16:31:05 +0000872static int l_divmod PROTO((longobject *, longobject *,
873 longobject **, longobject **));
874static int
875l_divmod(v, w, pdiv, pmod)
876 longobject *v;
877 longobject *w;
878 longobject **pdiv;
879 longobject **pmod;
880{
881 longobject *div, *mod;
882
883 if (long_divrem(v, w, &div, &mod) < 0)
884 return -1;
885 if (mod->ob_size < 0 && w->ob_size > 0 ||
886 mod->ob_size > 0 && w->ob_size < 0) {
887 longobject *temp;
888 longobject *one;
889 temp = (longobject *) long_add(mod, w);
890 DECREF(mod);
891 mod = temp;
892 if (mod == NULL) {
893 DECREF(div);
894 return -1;
895 }
896 one = (longobject *) newlongobject(1L);
897 if (one == NULL ||
898 (temp = (longobject *) long_sub(div, one)) == NULL) {
899 DECREF(mod);
900 DECREF(div);
Guido van Rossume5372401993-03-16 12:15:04 +0000901 XDECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000902 return -1;
903 }
Guido van Rossume5372401993-03-16 12:15:04 +0000904 DECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000905 DECREF(div);
906 div = temp;
907 }
908 *pdiv = div;
909 *pmod = mod;
910 return 0;
911}
912
913static object *
914long_div(v, w)
915 longobject *v;
916 longobject *w;
917{
918 longobject *div, *mod;
919 if (l_divmod(v, w, &div, &mod) < 0)
920 return NULL;
921 DECREF(mod);
922 return (object *)div;
923}
924
925static object *
926long_mod(v, w)
927 longobject *v;
928 longobject *w;
929{
930 longobject *div, *mod;
931 if (l_divmod(v, w, &div, &mod) < 0)
932 return NULL;
933 DECREF(div);
934 return (object *)mod;
935}
936
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000937static object *
938long_divmod(v, w)
939 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000940 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000941{
942 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000943 longobject *div, *mod;
944 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000945 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000946 z = newtupleobject(2);
947 if (z != NULL) {
948 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000949 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000950 }
951 else {
952 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000953 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000954 }
955 return z;
956}
957
958static object *
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000959long_pow(a, b, c)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000960 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000961 longobject *b;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000962 longobject *c;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000963{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000964 longobject *z, *div, *mod;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000965 int size_b, i;
966
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000967 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000968 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000969 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000970 return NULL;
971 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000972 z = (longobject *)newlongobject(1L);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000973 INCREF(a);
974 for (i = 0; i < size_b; ++i) {
975 digit bi = b->ob_digit[i];
976 int j;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000977
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000978 for (j = 0; j < SHIFT; ++j) {
979 longobject *temp;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000980
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000981 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000982 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000983 DECREF(z);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000984 if ((object*)c!=None && temp!=NULL) {
985 l_divmod(temp, c, &div, &mod);
986 XDECREF(div);
987 DECREF(temp);
988 temp = mod;
989 }
990 z = temp;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000991 if (z == NULL)
992 break;
993 }
994 bi >>= 1;
995 if (bi == 0 && i+1 == size_b)
996 break;
Guido van Rossume32e0141992-01-19 16:31:05 +0000997 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000998 DECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000999 if ((object*)c!=None && temp!=NULL) {
1000 l_divmod(temp, c, &div, &mod);
1001 XDECREF(div);
1002 DECREF(temp);
1003 temp = mod;
1004 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001005 a = temp;
1006 if (a == NULL) {
1007 DECREF(z);
1008 z = NULL;
1009 break;
1010 }
1011 }
Guido van Rossumc206c761995-01-10 15:23:19 +00001012 if (a == NULL || z == NULL)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001013 break;
1014 }
1015 XDECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001016 if ((object*)c!=None && z!=NULL) {
1017 l_divmod(z, c, &div, &mod);
1018 XDECREF(div);
1019 DECREF(z);
1020 z=mod;
1021 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001022 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001023}
1024
1025static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001026long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001027 longobject *v;
1028{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001029 /* Implement ~x as -(x+1) */
1030 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +00001031 longobject *w;
1032 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001033 if (w == NULL)
1034 return NULL;
1035 x = (longobject *) long_add(v, w);
1036 DECREF(w);
1037 if (x == NULL)
1038 return NULL;
1039 if (x->ob_size != 0)
1040 x->ob_size = -(x->ob_size);
1041 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001042}
1043
1044static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001045long_pos(v)
1046 longobject *v;
1047{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001048 INCREF(v);
1049 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001050}
1051
1052static object *
1053long_neg(v)
1054 longobject *v;
1055{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001056 longobject *z;
1057 int i, n;
1058 n = ABS(v->ob_size);
1059 if (n == 0) {
1060 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001061 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001062 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001063 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001064 z = alloclongobject(ABS(n));
1065 if (z == NULL)
1066 return NULL;
1067 for (i = 0; i < n; i++)
1068 z->ob_digit[i] = v->ob_digit[i];
1069 z->ob_size = -(v->ob_size);
1070 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001071}
1072
1073static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001074long_abs(v)
1075 longobject *v;
1076{
1077 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001078 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001079 else {
1080 INCREF(v);
1081 return (object *)v;
1082 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001083}
1084
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001085static int
1086long_nonzero(v)
1087 longobject *v;
1088{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001089 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001090}
1091
1092static object *
1093long_rshift(a, b)
1094 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001095 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001096{
1097 longobject *z;
1098 long shiftby;
1099 int newsize, wordshift, loshift, hishift, i, j;
1100 digit lomask, himask;
1101
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001102 if (a->ob_size < 0) {
1103 /* Right shifting negative numbers is harder */
1104 longobject *a1, *a2, *a3;
1105 a1 = (longobject *) long_invert(a);
1106 if (a1 == NULL) return NULL;
1107 a2 = (longobject *) long_rshift(a1, b);
1108 DECREF(a1);
1109 if (a2 == NULL) return NULL;
1110 a3 = (longobject *) long_invert(a2);
1111 DECREF(a2);
1112 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001113 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001114
1115 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001116 if (shiftby == -1L && err_occurred())
1117 return NULL;
1118 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001119 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001120 return NULL;
1121 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001122 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001123 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001124 if (newsize <= 0) {
1125 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001126 return (object *)z;
1127 }
1128 loshift = shiftby % SHIFT;
1129 hishift = SHIFT - loshift;
1130 lomask = ((digit)1 << hishift) - 1;
1131 himask = MASK ^ lomask;
1132 z = alloclongobject(newsize);
1133 if (z == NULL)
1134 return NULL;
1135 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001136 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001137 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1138 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1139 if (i+1 < newsize)
1140 z->ob_digit[i] |=
1141 (a->ob_digit[j+1] << hishift) & himask;
1142 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001143 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001144}
1145
1146static object *
1147long_lshift(a, b)
1148 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001149 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001150{
1151 longobject *z;
1152 long shiftby;
1153 int newsize, wordshift, loshift, hishift, i, j;
1154 digit lomask, himask;
1155
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001156 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001157 if (shiftby == -1L && err_occurred())
1158 return NULL;
1159 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001160 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001161 return NULL;
1162 }
1163 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001164 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001165 return NULL;
1166 }
1167 if (shiftby % SHIFT == 0) {
1168 wordshift = shiftby / SHIFT;
1169 loshift = 0;
1170 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001171 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001172 lomask = MASK;
1173 himask = 0;
1174 }
1175 else {
1176 wordshift = shiftby / SHIFT + 1;
1177 loshift = SHIFT - shiftby%SHIFT;
1178 hishift = shiftby % SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001179 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001180 lomask = ((digit)1 << hishift) - 1;
1181 himask = MASK ^ lomask;
1182 }
1183 z = alloclongobject(newsize);
1184 if (z == NULL)
1185 return NULL;
1186 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001187 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001188 for (i = 0; i < wordshift; i++)
1189 z->ob_digit[i] = 0;
1190 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1191 if (i > 0)
1192 z->ob_digit[i-1] |=
1193 (a->ob_digit[j] << hishift) & himask;
1194 z->ob_digit[i] =
1195 (a->ob_digit[j] >> loshift) & lomask;
1196 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001197 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001198}
1199
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001200
1201/* Bitwise and/xor/or operations */
1202
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001203#define MAX(x, y) ((x) < (y) ? (y) : (x))
1204#define MIN(x, y) ((x) > (y) ? (y) : (x))
1205
Guido van Rossume32e0141992-01-19 16:31:05 +00001206static object *long_bitwise PROTO((longobject *, int, longobject *));
1207static object *
1208long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001209 longobject *a;
1210 int op; /* '&', '|', '^' */
1211 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001212{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001213 digit maska, maskb; /* 0 or MASK */
1214 int negz;
1215 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001216 longobject *z;
1217 int i;
Guido van Rossum8b27d921992-03-27 17:27:05 +00001218 digit diga, digb;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001219 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001220
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001221 if (a->ob_size < 0) {
1222 a = (longobject *) long_invert(a);
1223 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001224 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001225 else {
1226 INCREF(a);
1227 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001228 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001229 if (b->ob_size < 0) {
1230 b = (longobject *) long_invert(b);
1231 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001232 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001233 else {
1234 INCREF(b);
1235 maskb = 0;
1236 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001237
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001238 size_a = a->ob_size;
1239 size_b = b->ob_size;
1240 size_z = MAX(size_a, size_b);
1241 z = alloclongobject(size_z);
1242 if (a == NULL || b == NULL || z == NULL) {
1243 XDECREF(a);
1244 XDECREF(b);
1245 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001246 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001247 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001248
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001249 negz = 0;
1250 switch (op) {
1251 case '^':
1252 if (maska != maskb) {
1253 maska ^= MASK;
1254 negz = -1;
1255 }
1256 break;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001257 case '&':
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001258 if (maska && maskb) {
1259 op = '|';
1260 maska ^= MASK;
1261 maskb ^= MASK;
1262 negz = -1;
1263 }
1264 break;
1265 case '|':
1266 if (maska || maskb) {
1267 op = '&';
1268 maska ^= MASK;
1269 maskb ^= MASK;
1270 negz = -1;
1271 }
1272 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001273 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001274
1275 for (i = 0; i < size_z; ++i) {
1276 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1277 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1278 switch (op) {
1279 case '&': z->ob_digit[i] = diga & digb; break;
1280 case '|': z->ob_digit[i] = diga | digb; break;
1281 case '^': z->ob_digit[i] = diga ^ digb; break;
1282 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001283 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001284
1285 DECREF(a);
1286 DECREF(b);
1287 z = long_normalize(z);
1288 if (negz == 0)
1289 return (object *) z;
1290 v = long_invert(z);
1291 DECREF(z);
1292 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001293}
1294
Guido van Rossumc6913e71991-11-19 20:26:46 +00001295static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001296long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001297 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001298 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001299{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001300 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001301}
1302
1303static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001304long_xor(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001305 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001306 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001307{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001308 return long_bitwise(a, '^', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001309}
1310
1311static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001312long_or(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001313 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001314 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001315{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001316 return long_bitwise(a, '|', b);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001317}
1318
Guido van Rossum234f9421993-06-17 12:35:49 +00001319static int
Guido van Rossume6eefc21992-08-14 12:06:52 +00001320long_coerce(pv, pw)
1321 object **pv;
1322 object **pw;
1323{
1324 if (is_intobject(*pw)) {
1325 *pw = newlongobject(getintvalue(*pw));
1326 INCREF(*pv);
1327 return 0;
1328 }
1329 return 1; /* Can't do it */
1330}
1331
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001332static object *
1333long_int(v)
1334 object *v;
1335{
1336 long x;
1337 x = getlongvalue(v);
1338 if (err_occurred())
1339 return NULL;
1340 return newintobject(x);
1341}
1342
1343static object *
1344long_long(v)
1345 object *v;
1346{
1347 INCREF(v);
1348 return v;
1349}
1350
1351static object *
1352long_float(v)
1353 object *v;
1354{
1355 return newfloatobject(dgetlongvalue(v));
1356}
1357
1358static object *
1359long_oct(v)
1360 object *v;
1361{
1362 return long_format(v, 8);
1363}
1364
1365static object *
1366long_hex(v)
1367 object *v;
1368{
1369 return long_format(v, 16);
1370}
1371
1372
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001373#define UF (unaryfunc)
1374#define BF (binaryfunc)
1375#define TF (ternaryfunc)
1376#define IF (inquiry)
Guido van Rossum8b27d921992-03-27 17:27:05 +00001377
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001378static number_methods long_as_number = {
Guido van Rossum8b27d921992-03-27 17:27:05 +00001379 BF long_add, /*nb_add*/
1380 BF long_sub, /*nb_subtract*/
1381 BF long_mul, /*nb_multiply*/
1382 BF long_div, /*nb_divide*/
1383 BF long_mod, /*nb_remainder*/
1384 BF long_divmod, /*nb_divmod*/
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001385 TF long_pow, /*nb_power*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001386 UF long_neg, /*nb_negative*/
1387 UF long_pos, /*tp_positive*/
1388 UF long_abs, /*tp_absolute*/
1389 IF long_nonzero,/*tp_nonzero*/
1390 UF long_invert, /*nb_invert*/
1391 BF long_lshift, /*nb_lshift*/
1392 BF long_rshift, /*nb_rshift*/
1393 BF long_and, /*nb_and*/
1394 BF long_xor, /*nb_xor*/
1395 BF long_or, /*nb_or*/
Guido van Rossume6eefc21992-08-14 12:06:52 +00001396 (int (*) FPROTO((object **, object **)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001397 (coercion)long_coerce, /*nb_coerce*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001398 UF long_int, /*nb_int*/
1399 UF long_long, /*nb_long*/
1400 UF long_float, /*nb_float*/
1401 UF long_oct, /*nb_oct*/
1402 UF long_hex, /*nb_hex*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001403};
1404
1405typeobject Longtype = {
1406 OB_HEAD_INIT(&Typetype)
1407 0,
1408 "long int",
1409 sizeof(longobject) - sizeof(digit),
1410 sizeof(digit),
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001411 (destructor)long_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001412 0, /*tp_print*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001413 0, /*tp_getattr*/
1414 0, /*tp_setattr*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001415 (int (*) FPROTO((object *, object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001416 (cmpfunc)long_compare, /*tp_compare*/
1417 (reprfunc)long_repr, /*tp_repr*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001418 &long_as_number,/*tp_as_number*/
1419 0, /*tp_as_sequence*/
1420 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +00001421 (long (*) FPROTO((object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001422 (hashfunc)long_hash, /*tp_hash*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001423};