blob: ef3f332b2db02e2b41f6b91f980ea67a69a20d75 [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 Rossum149e9ea1991-06-03 10:58:24 +000031#include <math.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 *
105dnewlongobject(dval)
106 double dval;
107{
108 longobject *v;
109 double frac;
110 int i, ndig, expo, neg;
111 neg = 0;
112 if (dval < 0.0) {
113 neg = 1;
114 dval = -dval;
115 }
116 frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
117 if (expo <= 0)
118 return newlongobject(0L);
119 ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
120 v = alloclongobject(ndig);
121 if (v == NULL)
122 return NULL;
123 frac = ldexp(frac, (expo-1) % SHIFT + 1);
124 for (i = ndig; --i >= 0; ) {
125 long bits = (long)frac;
126 v->ob_digit[i] = bits;
127 frac = frac - (double)bits;
128 frac = ldexp(frac, SHIFT);
129 }
130 if (neg)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000131 v->ob_size = -(v->ob_size);
Guido van Rossum149e9ea1991-06-03 10:58:24 +0000132 return (object *)v;
133}
134
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000135/* Get a C long int from a long int object.
136 Returns -1 and sets an error condition if overflow occurs. */
137
138long
139getlongvalue(vv)
140 object *vv;
141{
142 register longobject *v;
143 long x, prev;
144 int i, sign;
145
146 if (vv == NULL || !is_longobject(vv)) {
147 err_badcall();
148 return -1;
149 }
150 v = (longobject *)vv;
151 i = v->ob_size;
152 sign = 1;
153 x = 0;
154 if (i < 0) {
155 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000156 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000157 }
158 while (--i >= 0) {
159 prev = x;
160 x = (x << SHIFT) + v->ob_digit[i];
161 if ((x >> SHIFT) != prev) {
Guido van Rossum03093a21994-09-28 15:51:32 +0000162 err_setstr(OverflowError,
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000163 "long int too long to convert");
164 return -1;
165 }
166 }
167 return x * sign;
168}
169
170/* Get a C double from a long int object. No overflow check. */
171
172double
173dgetlongvalue(vv)
174 object *vv;
175{
176 register longobject *v;
177 double x;
178 double multiplier = (double) (1L << SHIFT);
179 int i, sign;
180
181 if (vv == NULL || !is_longobject(vv)) {
182 err_badcall();
183 return -1;
184 }
185 v = (longobject *)vv;
186 i = v->ob_size;
187 sign = 1;
188 x = 0.0;
189 if (i < 0) {
190 sign = -1;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000191 i = -(i);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000192 }
193 while (--i >= 0) {
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000194 x = x*multiplier + (double)v->ob_digit[i];
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000195 }
196 return x * sign;
197}
198
199/* Multiply by a single digit, ignoring the sign. */
200
Guido van Rossume32e0141992-01-19 16:31:05 +0000201static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000202mul1(a, n)
203 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000204 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000205{
206 return muladd1(a, n, (digit)0);
207}
208
209/* Multiply by a single digit and add a single digit, ignoring the sign. */
210
Guido van Rossume32e0141992-01-19 16:31:05 +0000211static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000212muladd1(a, n, extra)
213 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000214 wdigit n;
215 wdigit extra;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000216{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000217 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000218 longobject *z = alloclongobject(size_a+1);
219 twodigits carry = extra;
220 int i;
221
222 if (z == NULL)
223 return NULL;
224 for (i = 0; i < size_a; ++i) {
225 carry += (twodigits)a->ob_digit[i] * n;
226 z->ob_digit[i] = carry & MASK;
227 carry >>= SHIFT;
228 }
229 z->ob_digit[i] = carry;
230 return long_normalize(z);
231}
232
233/* Divide a long integer by a digit, returning both the quotient
234 (as function result) and the remainder (through *prem).
235 The sign of a is ignored; n should not be zero. */
236
Guido van Rossume32e0141992-01-19 16:31:05 +0000237static longobject *
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000238divrem1(a, n, prem)
239 longobject *a;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000240 wdigit n;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000241 digit *prem;
242{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000243 int size = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000244 longobject *z;
245 int i;
246 twodigits rem = 0;
247
248 assert(n > 0 && n <= MASK);
249 z = alloclongobject(size);
250 if (z == NULL)
251 return NULL;
252 for (i = size; --i >= 0; ) {
253 rem = (rem << SHIFT) + a->ob_digit[i];
254 z->ob_digit[i] = rem/n;
255 rem %= n;
256 }
257 *prem = rem;
258 return long_normalize(z);
259}
260
261/* Convert a long int object to a string, using a given conversion base.
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000262 Return a string object.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000263 If base is 8 or 16, add the proper prefix '0' or '0x'.
264 External linkage: used in bltinmodule.c by hex() and oct(). */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000265
Guido van Rossum234f9421993-06-17 12:35:49 +0000266static object *
Guido van Rossume32e0141992-01-19 16:31:05 +0000267long_format(aa, base)
268 object *aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000269 int base;
270{
Guido van Rossume32e0141992-01-19 16:31:05 +0000271 register longobject *a = (longobject *)aa;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000272 stringobject *str;
273 int i;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000274 int size_a = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000275 char *p;
276 int bits;
277 char sign = '\0';
Guido van Rossume32e0141992-01-19 16:31:05 +0000278
279 if (a == NULL || !is_longobject(a)) {
280 err_badcall();
281 return NULL;
282 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000283 assert(base >= 2 && base <= 36);
284
285 /* Compute a rough upper bound for the length of the string */
286 i = base;
287 bits = 0;
288 while (i > 1) {
289 ++bits;
290 i >>= 1;
291 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000292 i = 6 + (size_a*SHIFT + bits-1) / bits;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000293 str = (stringobject *) newsizedstringobject((char *)0, i);
294 if (str == NULL)
295 return NULL;
296 p = GETSTRINGVALUE(str) + i;
297 *p = '\0';
Guido van Rossumc6913e71991-11-19 20:26:46 +0000298 *--p = 'L';
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000299 if (a->ob_size < 0)
300 sign = '-';
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000301
302 INCREF(a);
303 do {
304 digit rem;
305 longobject *temp = divrem1(a, (digit)base, &rem);
306 if (temp == NULL) {
307 DECREF(a);
308 DECREF(str);
309 return NULL;
310 }
311 if (rem < 10)
312 rem += '0';
313 else
314 rem += 'A'-10;
315 assert(p > GETSTRINGVALUE(str));
316 *--p = rem;
317 DECREF(a);
318 a = temp;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000319 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000320 DECREF(a);
321 DECREF(str);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000322 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000323 })
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000324 } while (ABS(a->ob_size) != 0);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000325 DECREF(a);
Guido van Rossum2c475421992-08-14 15:13:07 +0000326 if (base == 8) {
327 if (size_a != 0)
328 *--p = '0';
329 }
Guido van Rossum3d3037d1991-10-24 14:55:57 +0000330 else if (base == 16) {
331 *--p = 'x';
332 *--p = '0';
333 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000334 else if (base != 10) {
335 *--p = '#';
336 *--p = '0' + base%10;
337 if (base > 10)
338 *--p = '0' + base/10;
339 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000340 if (sign)
341 *--p = sign;
342 if (p != GETSTRINGVALUE(str)) {
343 char *q = GETSTRINGVALUE(str);
344 assert(p > q);
345 do {
346 } while ((*q++ = *p++) != '\0');
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000347 q--;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000348 resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
349 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000350 return (object *)str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000351}
352
353/* Convert a string to a long int object, in a given base.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000354 Base zero implies a default depending on the number.
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000355 External linkage: used in compile.c and stropmodule.c. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000356
357object *
358long_scan(str, base)
359 char *str;
360 int base;
361{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000362 return long_escan(str, (char **)NULL, base);
363}
364
365object *
366long_escan(str, pend, base)
367 char *str;
368 char **pend;
369 int base;
370{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000371 int sign = 1;
372 longobject *z;
373
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000374 if (base != 0 && base < 2 || base > 36) {
375 err_setstr(ValueError, "invalid base for long literal");
376 return NULL;
377 }
378 while (*str != '\0' && isspace(*str))
379 str++;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000380 if (*str == '+')
381 ++str;
382 else if (*str == '-') {
383 ++str;
384 sign = -1;
385 }
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000386 while (*str != '\0' && isspace(*str))
387 str++;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000388 if (base == 0) {
389 if (str[0] != '0')
390 base = 10;
391 else if (str[1] == 'x' || str[1] == 'X')
392 base = 16;
393 else
394 base = 8;
395 }
396 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
397 str += 2;
398 z = alloclongobject(0);
399 for ( ; z != NULL; ++str) {
400 int k = -1;
401 longobject *temp;
402
403 if (*str <= '9')
404 k = *str - '0';
405 else if (*str >= 'a')
406 k = *str - 'a' + 10;
407 else if (*str >= 'A')
408 k = *str - 'A' + 10;
409 if (k < 0 || k >= base)
410 break;
411 temp = muladd1(z, (digit)base, (digit)k);
412 DECREF(z);
413 z = temp;
414 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000415 if (sign < 0 && z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000416 z->ob_size = -(z->ob_size);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000417 if (pend)
418 *pend = str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000419 return (object *) z;
420}
421
422static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
Guido van Rossumc6913e71991-11-19 20:26:46 +0000423static object *long_pos PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000424static long_divrem PROTO((longobject *, longobject *,
425 longobject **, longobject **));
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000426
427/* Long division with remainder, top-level routine */
428
Guido van Rossume32e0141992-01-19 16:31:05 +0000429static int
430long_divrem(a, b, pdiv, prem)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000431 longobject *a, *b;
Guido van Rossume32e0141992-01-19 16:31:05 +0000432 longobject **pdiv;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000433 longobject **prem;
434{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000435 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000436 longobject *z;
437
438 if (size_b == 0) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000439 err_setstr(ZeroDivisionError, "long division or modulo");
440 return -1;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000441 }
442 if (size_a < size_b ||
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000443 size_a == size_b &&
444 a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000445 /* |a| < |b|. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000446 *pdiv = alloclongobject(0);
447 INCREF(a);
448 *prem = (longobject *) a;
449 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000450 }
451 if (size_b == 1) {
452 digit rem = 0;
453 z = divrem1(a, b->ob_digit[0], &rem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000454 if (z == NULL)
455 return -1;
456 *prem = (longobject *) newlongobject((long)rem);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000457 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000458 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000459 z = x_divrem(a, b, prem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000460 if (z == NULL)
461 return -1;
462 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000463 /* Set the signs.
464 The quotient z has the sign of a*b;
465 the remainder r has the sign of a,
466 so a = b*z + r. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000467 if ((a->ob_size < 0) != (b->ob_size < 0))
468 z->ob_size = -(z->ob_size);
469 if (a->ob_size < 0 && (*prem)->ob_size != 0)
470 (*prem)->ob_size = -((*prem)->ob_size);
471 *pdiv = z;
472 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000473}
474
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000475/* Unsigned long division with remainder -- the algorithm */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000476
477static longobject *
478x_divrem(v1, w1, prem)
479 longobject *v1, *w1;
480 longobject **prem;
481{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000482 int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000483 digit d = (twodigits)BASE / (w1->ob_digit[size_w-1] + 1);
484 longobject *v = mul1(v1, d);
485 longobject *w = mul1(w1, d);
486 longobject *a;
487 int j, k;
488
489 if (v == NULL || w == NULL) {
490 XDECREF(v);
491 XDECREF(w);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000492 return NULL;
493 }
494
495 assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000496 assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000497 assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000498
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000499 size_v = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000500 a = alloclongobject(size_v - size_w + 1);
501
502 for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
503 digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
504 twodigits q;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000505 stwodigits carry = 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000506 int i;
507
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000508 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000509 DECREF(a);
510 a = NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000511 break;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000512 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000513 if (vj == w->ob_digit[size_w-1])
514 q = MASK;
515 else
516 q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
517 w->ob_digit[size_w-1];
518
519 while (w->ob_digit[size_w-2]*q >
520 ((
521 ((twodigits)vj << SHIFT)
522 + v->ob_digit[j-1]
523 - q*w->ob_digit[size_w-1]
524 ) << SHIFT)
525 + v->ob_digit[j-2])
526 --q;
527
528 for (i = 0; i < size_w && i+k < size_v; ++i) {
529 twodigits z = w->ob_digit[i] * q;
530 digit zz = z >> SHIFT;
531 carry += v->ob_digit[i+k] - z + ((twodigits)zz << SHIFT);
532 v->ob_digit[i+k] = carry & MASK;
533 carry = (carry >> SHIFT) - zz;
534 }
535
536 if (i+k < size_v) {
537 carry += v->ob_digit[i+k];
538 v->ob_digit[i+k] = 0;
539 }
540
541 if (carry == 0)
542 a->ob_digit[k] = q;
543 else {
544 assert(carry == -1);
545 a->ob_digit[k] = q-1;
546 carry = 0;
547 for (i = 0; i < size_w && i+k < size_v; ++i) {
548 carry += v->ob_digit[i+k] + w->ob_digit[i];
549 v->ob_digit[i+k] = carry & MASK;
550 carry >>= SHIFT;
551 }
552 }
553 } /* for j, k */
554
Guido van Rossumc206c761995-01-10 15:23:19 +0000555 if (a == NULL)
556 *prem = NULL;
557 else {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000558 a = long_normalize(a);
Guido van Rossume32e0141992-01-19 16:31:05 +0000559 *prem = divrem1(v, d, &d);
560 /* d receives the (unused) remainder */
561 if (*prem == NULL) {
562 DECREF(a);
563 a = NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000564 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000565 }
566 DECREF(v);
567 DECREF(w);
568 return a;
569}
570
571/* Methods */
572
Guido van Rossume32e0141992-01-19 16:31:05 +0000573/* Forward */
Guido van Rossum8b27d921992-03-27 17:27:05 +0000574static void long_dealloc PROTO((object *));
Guido van Rossum8b27d921992-03-27 17:27:05 +0000575static object *long_repr PROTO((object *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000576static int long_compare PROTO((longobject *, longobject *));
Guido van Rossum9bfef441993-03-29 10:43:31 +0000577static long long_hash PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000578
579static object *long_add PROTO((longobject *, longobject *));
580static object *long_sub PROTO((longobject *, longobject *));
581static object *long_mul PROTO((longobject *, longobject *));
582static object *long_div PROTO((longobject *, longobject *));
583static object *long_mod PROTO((longobject *, longobject *));
584static object *long_divmod PROTO((longobject *, longobject *));
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000585static object *long_pow PROTO((longobject *, longobject *, longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000586static object *long_neg PROTO((longobject *));
587static object *long_pos PROTO((longobject *));
588static object *long_abs PROTO((longobject *));
589static int long_nonzero PROTO((longobject *));
590static object *long_invert PROTO((longobject *));
591static object *long_lshift PROTO((longobject *, longobject *));
592static object *long_rshift PROTO((longobject *, longobject *));
593static object *long_and PROTO((longobject *, longobject *));
594static object *long_xor PROTO((longobject *, longobject *));
595static object *long_or PROTO((longobject *, longobject *));
596
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000597static void
598long_dealloc(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000599 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000600{
601 DEL(v);
602}
603
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000604static object *
605long_repr(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000606 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000607{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000608 return long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000609}
610
611static int
612long_compare(a, b)
613 longobject *a, *b;
614{
615 int sign;
616
Guido van Rossumc6913e71991-11-19 20:26:46 +0000617 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000618 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000619 sign = 0;
620 else
621 sign = a->ob_size - b->ob_size;
622 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000623 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000624 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000625 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
626 ;
627 if (i < 0)
628 sign = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000629 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000630 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000631 if (a->ob_size < 0)
632 sign = -sign;
633 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000634 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000635 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000636}
637
Guido van Rossum9bfef441993-03-29 10:43:31 +0000638static long
639long_hash(v)
640 longobject *v;
641{
642 long x;
643 int i, sign;
644
645 /* This is designed so that Python ints and longs with the
646 same value hash to the same value, otherwise comparisons
647 of mapping keys will turn out weird */
648 i = v->ob_size;
649 sign = 1;
650 x = 0;
651 if (i < 0) {
652 sign = -1;
653 i = -(i);
654 }
655 while (--i >= 0) {
656 /* Force a 32-bit circular shift */
657 x = ((x << SHIFT) & ~MASK) | ((x >> (32-SHIFT)) & MASK);
658 x += v->ob_digit[i];
659 }
660 x = x * sign;
661 if (x == -1)
662 x = -2;
663 return x;
664}
665
666
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000667/* Add the absolute values of two long integers. */
668
669static longobject *x_add PROTO((longobject *, longobject *));
670static longobject *
671x_add(a, b)
672 longobject *a, *b;
673{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000674 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000675 longobject *z;
676 int i;
677 digit carry = 0;
678
679 /* Ensure a is the larger of the two: */
680 if (size_a < size_b) {
681 { longobject *temp = a; a = b; b = temp; }
682 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
683 }
684 z = alloclongobject(size_a+1);
685 if (z == NULL)
686 return NULL;
687 for (i = 0; i < size_b; ++i) {
688 carry += a->ob_digit[i] + b->ob_digit[i];
689 z->ob_digit[i] = carry & MASK;
690 /* The following assumes unsigned shifts don't
691 propagate the sign bit. */
692 carry >>= SHIFT;
693 }
694 for (; i < size_a; ++i) {
695 carry += a->ob_digit[i];
696 z->ob_digit[i] = carry & MASK;
697 carry >>= SHIFT;
698 }
699 z->ob_digit[i] = carry;
700 return long_normalize(z);
701}
702
703/* Subtract the absolute values of two integers. */
704
705static longobject *x_sub PROTO((longobject *, longobject *));
706static longobject *
707x_sub(a, b)
708 longobject *a, *b;
709{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000710 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000711 longobject *z;
712 int i;
713 int sign = 1;
714 digit borrow = 0;
715
716 /* Ensure a is the larger of the two: */
717 if (size_a < size_b) {
718 sign = -1;
719 { longobject *temp = a; a = b; b = temp; }
720 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
721 }
722 else if (size_a == size_b) {
723 /* Find highest digit where a and b differ: */
724 i = size_a;
725 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
726 ;
727 if (i < 0)
728 return alloclongobject(0);
729 if (a->ob_digit[i] < b->ob_digit[i]) {
730 sign = -1;
731 { longobject *temp = a; a = b; b = temp; }
732 }
733 size_a = size_b = i+1;
734 }
735 z = alloclongobject(size_a);
736 if (z == NULL)
737 return NULL;
738 for (i = 0; i < size_b; ++i) {
739 /* The following assumes unsigned arithmetic
740 works module 2**N for some N>SHIFT. */
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000741 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000742 z->ob_digit[i] = borrow & MASK;
743 borrow >>= SHIFT;
744 borrow &= 1; /* Keep only one sign bit */
745 }
746 for (; i < size_a; ++i) {
747 borrow = a->ob_digit[i] - borrow;
748 z->ob_digit[i] = borrow & MASK;
749 borrow >>= SHIFT;
750 }
751 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000752 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000753 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000754 return long_normalize(z);
755}
756
757static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000758long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000759 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000760 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000761{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000762 longobject *z;
763
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000764 if (a->ob_size < 0) {
765 if (b->ob_size < 0) {
766 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000767 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000768 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000769 }
770 else
771 z = x_sub(b, a);
772 }
773 else {
774 if (b->ob_size < 0)
775 z = x_sub(a, b);
776 else
777 z = x_add(a, b);
778 }
779 return (object *)z;
780}
781
782static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000783long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000784 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000785 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000786{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000787 longobject *z;
788
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000789 if (a->ob_size < 0) {
790 if (b->ob_size < 0)
791 z = x_sub(a, b);
792 else
793 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000794 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000795 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000796 }
797 else {
798 if (b->ob_size < 0)
799 z = x_add(a, b);
800 else
801 z = x_sub(a, b);
802 }
803 return (object *)z;
804}
805
806static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000807long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000808 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000809 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000810{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000811 int size_a;
812 int size_b;
813 longobject *z;
814 int i;
815
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000816 size_a = ABS(a->ob_size);
817 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000818 z = alloclongobject(size_a + size_b);
819 if (z == NULL)
820 return NULL;
821 for (i = 0; i < z->ob_size; ++i)
822 z->ob_digit[i] = 0;
823 for (i = 0; i < size_a; ++i) {
824 twodigits carry = 0;
825 twodigits f = a->ob_digit[i];
826 int j;
827
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000828 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000829 DECREF(z);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000830 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000831 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000832 for (j = 0; j < size_b; ++j) {
833 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
834 z->ob_digit[i+j] = carry & MASK;
835 carry >>= SHIFT;
836 }
837 for (; carry != 0; ++j) {
838 assert(i+j < z->ob_size);
839 carry += z->ob_digit[i+j];
840 z->ob_digit[i+j] = carry & MASK;
841 carry >>= SHIFT;
842 }
843 }
844 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000845 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000846 if (b->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000847 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000848 return (object *) long_normalize(z);
849}
850
Guido van Rossume32e0141992-01-19 16:31:05 +0000851/* The / and % operators are now defined in terms of divmod().
852 The expression a mod b has the value a - b*floor(a/b).
853 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000854 |a| by |b|, with the sign of a. This is also expressed
855 as a - b*trunc(a/b), if trunc truncates towards zero.
856 Some examples:
857 a b a rem b a mod b
858 13 10 3 3
859 -13 10 -3 7
860 13 -10 3 -7
861 -13 -10 -3 -3
862 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000863 have different signs. We then subtract one from the 'div'
864 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000865
Guido van Rossume32e0141992-01-19 16:31:05 +0000866static int l_divmod PROTO((longobject *, longobject *,
867 longobject **, longobject **));
868static int
869l_divmod(v, w, pdiv, pmod)
870 longobject *v;
871 longobject *w;
872 longobject **pdiv;
873 longobject **pmod;
874{
875 longobject *div, *mod;
876
877 if (long_divrem(v, w, &div, &mod) < 0)
878 return -1;
879 if (mod->ob_size < 0 && w->ob_size > 0 ||
880 mod->ob_size > 0 && w->ob_size < 0) {
881 longobject *temp;
882 longobject *one;
883 temp = (longobject *) long_add(mod, w);
884 DECREF(mod);
885 mod = temp;
886 if (mod == NULL) {
887 DECREF(div);
888 return -1;
889 }
890 one = (longobject *) newlongobject(1L);
891 if (one == NULL ||
892 (temp = (longobject *) long_sub(div, one)) == NULL) {
893 DECREF(mod);
894 DECREF(div);
Guido van Rossume5372401993-03-16 12:15:04 +0000895 XDECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000896 return -1;
897 }
Guido van Rossume5372401993-03-16 12:15:04 +0000898 DECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000899 DECREF(div);
900 div = temp;
901 }
902 *pdiv = div;
903 *pmod = mod;
904 return 0;
905}
906
907static object *
908long_div(v, w)
909 longobject *v;
910 longobject *w;
911{
912 longobject *div, *mod;
913 if (l_divmod(v, w, &div, &mod) < 0)
914 return NULL;
915 DECREF(mod);
916 return (object *)div;
917}
918
919static object *
920long_mod(v, w)
921 longobject *v;
922 longobject *w;
923{
924 longobject *div, *mod;
925 if (l_divmod(v, w, &div, &mod) < 0)
926 return NULL;
927 DECREF(div);
928 return (object *)mod;
929}
930
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000931static object *
932long_divmod(v, w)
933 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000934 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000935{
936 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000937 longobject *div, *mod;
938 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000939 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000940 z = newtupleobject(2);
941 if (z != NULL) {
942 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000943 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000944 }
945 else {
946 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000947 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000948 }
949 return z;
950}
951
952static object *
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000953long_pow(a, b, c)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000954 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000955 longobject *b;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000956 longobject *c;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000957{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000958 longobject *z, *div, *mod;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000959 int size_b, i;
960
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000961 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000962 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000963 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000964 return NULL;
965 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000966 z = (longobject *)newlongobject(1L);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000967 INCREF(a);
968 for (i = 0; i < size_b; ++i) {
969 digit bi = b->ob_digit[i];
970 int j;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000971
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000972 for (j = 0; j < SHIFT; ++j) {
973 longobject *temp;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000974
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000975 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000976 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000977 DECREF(z);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000978 if ((object*)c!=None && temp!=NULL) {
979 l_divmod(temp, c, &div, &mod);
980 XDECREF(div);
981 DECREF(temp);
982 temp = mod;
983 }
984 z = temp;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000985 if (z == NULL)
986 break;
987 }
988 bi >>= 1;
989 if (bi == 0 && i+1 == size_b)
990 break;
Guido van Rossume32e0141992-01-19 16:31:05 +0000991 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000992 DECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000993 if ((object*)c!=None && temp!=NULL) {
994 l_divmod(temp, c, &div, &mod);
995 XDECREF(div);
996 DECREF(temp);
997 temp = mod;
998 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000999 a = temp;
1000 if (a == NULL) {
1001 DECREF(z);
1002 z = NULL;
1003 break;
1004 }
1005 }
Guido van Rossumc206c761995-01-10 15:23:19 +00001006 if (a == NULL || z == NULL)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001007 break;
1008 }
1009 XDECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001010 if ((object*)c!=None && z!=NULL) {
1011 l_divmod(z, c, &div, &mod);
1012 XDECREF(div);
1013 DECREF(z);
1014 z=mod;
1015 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001016 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001017}
1018
1019static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001020long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001021 longobject *v;
1022{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001023 /* Implement ~x as -(x+1) */
1024 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +00001025 longobject *w;
1026 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001027 if (w == NULL)
1028 return NULL;
1029 x = (longobject *) long_add(v, w);
1030 DECREF(w);
1031 if (x == NULL)
1032 return NULL;
1033 if (x->ob_size != 0)
1034 x->ob_size = -(x->ob_size);
1035 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001036}
1037
1038static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001039long_pos(v)
1040 longobject *v;
1041{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001042 INCREF(v);
1043 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001044}
1045
1046static object *
1047long_neg(v)
1048 longobject *v;
1049{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001050 longobject *z;
1051 int i, n;
1052 n = ABS(v->ob_size);
1053 if (n == 0) {
1054 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001055 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001056 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001057 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001058 z = alloclongobject(ABS(n));
1059 if (z == NULL)
1060 return NULL;
1061 for (i = 0; i < n; i++)
1062 z->ob_digit[i] = v->ob_digit[i];
1063 z->ob_size = -(v->ob_size);
1064 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001065}
1066
1067static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001068long_abs(v)
1069 longobject *v;
1070{
1071 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001072 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001073 else {
1074 INCREF(v);
1075 return (object *)v;
1076 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001077}
1078
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001079static int
1080long_nonzero(v)
1081 longobject *v;
1082{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001083 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001084}
1085
1086static object *
1087long_rshift(a, b)
1088 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001089 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001090{
1091 longobject *z;
1092 long shiftby;
1093 int newsize, wordshift, loshift, hishift, i, j;
1094 digit lomask, himask;
1095
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001096 if (a->ob_size < 0) {
1097 /* Right shifting negative numbers is harder */
1098 longobject *a1, *a2, *a3;
1099 a1 = (longobject *) long_invert(a);
1100 if (a1 == NULL) return NULL;
1101 a2 = (longobject *) long_rshift(a1, b);
1102 DECREF(a1);
1103 if (a2 == NULL) return NULL;
1104 a3 = (longobject *) long_invert(a2);
1105 DECREF(a2);
1106 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001107 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001108
1109 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001110 if (shiftby == -1L && err_occurred())
1111 return NULL;
1112 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001113 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001114 return NULL;
1115 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001116 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001117 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001118 if (newsize <= 0) {
1119 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001120 return (object *)z;
1121 }
1122 loshift = shiftby % SHIFT;
1123 hishift = SHIFT - loshift;
1124 lomask = ((digit)1 << hishift) - 1;
1125 himask = MASK ^ lomask;
1126 z = alloclongobject(newsize);
1127 if (z == NULL)
1128 return NULL;
1129 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001130 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001131 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1132 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1133 if (i+1 < newsize)
1134 z->ob_digit[i] |=
1135 (a->ob_digit[j+1] << hishift) & himask;
1136 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001137 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001138}
1139
1140static object *
1141long_lshift(a, b)
1142 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001143 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001144{
1145 longobject *z;
1146 long shiftby;
1147 int newsize, wordshift, loshift, hishift, i, j;
1148 digit lomask, himask;
1149
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001150 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001151 if (shiftby == -1L && err_occurred())
1152 return NULL;
1153 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001154 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001155 return NULL;
1156 }
1157 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001158 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001159 return NULL;
1160 }
1161 if (shiftby % SHIFT == 0) {
1162 wordshift = shiftby / SHIFT;
1163 loshift = 0;
1164 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001165 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001166 lomask = MASK;
1167 himask = 0;
1168 }
1169 else {
1170 wordshift = shiftby / SHIFT + 1;
1171 loshift = SHIFT - shiftby%SHIFT;
1172 hishift = shiftby % SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001173 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001174 lomask = ((digit)1 << hishift) - 1;
1175 himask = MASK ^ lomask;
1176 }
1177 z = alloclongobject(newsize);
1178 if (z == NULL)
1179 return NULL;
1180 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001181 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001182 for (i = 0; i < wordshift; i++)
1183 z->ob_digit[i] = 0;
1184 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1185 if (i > 0)
1186 z->ob_digit[i-1] |=
1187 (a->ob_digit[j] << hishift) & himask;
1188 z->ob_digit[i] =
1189 (a->ob_digit[j] >> loshift) & lomask;
1190 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001191 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001192}
1193
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001194
1195/* Bitwise and/xor/or operations */
1196
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001197#define MAX(x, y) ((x) < (y) ? (y) : (x))
1198#define MIN(x, y) ((x) > (y) ? (y) : (x))
1199
Guido van Rossume32e0141992-01-19 16:31:05 +00001200static object *long_bitwise PROTO((longobject *, int, longobject *));
1201static object *
1202long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001203 longobject *a;
1204 int op; /* '&', '|', '^' */
1205 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001206{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001207 digit maska, maskb; /* 0 or MASK */
1208 int negz;
1209 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001210 longobject *z;
1211 int i;
Guido van Rossum8b27d921992-03-27 17:27:05 +00001212 digit diga, digb;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001213 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001214
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001215 if (a->ob_size < 0) {
1216 a = (longobject *) long_invert(a);
1217 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001218 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001219 else {
1220 INCREF(a);
1221 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001222 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001223 if (b->ob_size < 0) {
1224 b = (longobject *) long_invert(b);
1225 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001226 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001227 else {
1228 INCREF(b);
1229 maskb = 0;
1230 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001231
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001232 size_a = a->ob_size;
1233 size_b = b->ob_size;
1234 size_z = MAX(size_a, size_b);
1235 z = alloclongobject(size_z);
1236 if (a == NULL || b == NULL || z == NULL) {
1237 XDECREF(a);
1238 XDECREF(b);
1239 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001240 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001241 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001242
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001243 negz = 0;
1244 switch (op) {
1245 case '^':
1246 if (maska != maskb) {
1247 maska ^= MASK;
1248 negz = -1;
1249 }
1250 break;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001251 case '&':
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001252 if (maska && maskb) {
1253 op = '|';
1254 maska ^= MASK;
1255 maskb ^= MASK;
1256 negz = -1;
1257 }
1258 break;
1259 case '|':
1260 if (maska || maskb) {
1261 op = '&';
1262 maska ^= MASK;
1263 maskb ^= MASK;
1264 negz = -1;
1265 }
1266 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001267 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001268
1269 for (i = 0; i < size_z; ++i) {
1270 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1271 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1272 switch (op) {
1273 case '&': z->ob_digit[i] = diga & digb; break;
1274 case '|': z->ob_digit[i] = diga | digb; break;
1275 case '^': z->ob_digit[i] = diga ^ digb; break;
1276 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001277 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001278
1279 DECREF(a);
1280 DECREF(b);
1281 z = long_normalize(z);
1282 if (negz == 0)
1283 return (object *) z;
1284 v = long_invert(z);
1285 DECREF(z);
1286 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001287}
1288
Guido van Rossumc6913e71991-11-19 20:26:46 +00001289static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001290long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001291 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001292 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001293{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001294 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001295}
1296
1297static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001298long_xor(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001299 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001300 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001301{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001302 return long_bitwise(a, '^', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001303}
1304
1305static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001306long_or(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001307 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001308 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001309{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001310 return long_bitwise(a, '|', b);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001311}
1312
Guido van Rossum234f9421993-06-17 12:35:49 +00001313static int
Guido van Rossume6eefc21992-08-14 12:06:52 +00001314long_coerce(pv, pw)
1315 object **pv;
1316 object **pw;
1317{
1318 if (is_intobject(*pw)) {
1319 *pw = newlongobject(getintvalue(*pw));
1320 INCREF(*pv);
1321 return 0;
1322 }
1323 return 1; /* Can't do it */
1324}
1325
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001326static object *
1327long_int(v)
1328 object *v;
1329{
1330 long x;
1331 x = getlongvalue(v);
1332 if (err_occurred())
1333 return NULL;
1334 return newintobject(x);
1335}
1336
1337static object *
1338long_long(v)
1339 object *v;
1340{
1341 INCREF(v);
1342 return v;
1343}
1344
1345static object *
1346long_float(v)
1347 object *v;
1348{
1349 return newfloatobject(dgetlongvalue(v));
1350}
1351
1352static object *
1353long_oct(v)
1354 object *v;
1355{
1356 return long_format(v, 8);
1357}
1358
1359static object *
1360long_hex(v)
1361 object *v;
1362{
1363 return long_format(v, 16);
1364}
1365
1366
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001367#define UF (unaryfunc)
1368#define BF (binaryfunc)
1369#define TF (ternaryfunc)
1370#define IF (inquiry)
Guido van Rossum8b27d921992-03-27 17:27:05 +00001371
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001372static number_methods long_as_number = {
Guido van Rossum8b27d921992-03-27 17:27:05 +00001373 BF long_add, /*nb_add*/
1374 BF long_sub, /*nb_subtract*/
1375 BF long_mul, /*nb_multiply*/
1376 BF long_div, /*nb_divide*/
1377 BF long_mod, /*nb_remainder*/
1378 BF long_divmod, /*nb_divmod*/
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001379 TF long_pow, /*nb_power*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001380 UF long_neg, /*nb_negative*/
1381 UF long_pos, /*tp_positive*/
1382 UF long_abs, /*tp_absolute*/
1383 IF long_nonzero,/*tp_nonzero*/
1384 UF long_invert, /*nb_invert*/
1385 BF long_lshift, /*nb_lshift*/
1386 BF long_rshift, /*nb_rshift*/
1387 BF long_and, /*nb_and*/
1388 BF long_xor, /*nb_xor*/
1389 BF long_or, /*nb_or*/
Guido van Rossume6eefc21992-08-14 12:06:52 +00001390 (int (*) FPROTO((object **, object **)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001391 (coercion)long_coerce, /*nb_coerce*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001392 UF long_int, /*nb_int*/
1393 UF long_long, /*nb_long*/
1394 UF long_float, /*nb_float*/
1395 UF long_oct, /*nb_oct*/
1396 UF long_hex, /*nb_hex*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001397};
1398
1399typeobject Longtype = {
1400 OB_HEAD_INIT(&Typetype)
1401 0,
1402 "long int",
1403 sizeof(longobject) - sizeof(digit),
1404 sizeof(digit),
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001405 (destructor)long_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001406 0, /*tp_print*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001407 0, /*tp_getattr*/
1408 0, /*tp_setattr*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001409 (int (*) FPROTO((object *, object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001410 (cmpfunc)long_compare, /*tp_compare*/
1411 (reprfunc)long_repr, /*tp_repr*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001412 &long_as_number,/*tp_as_number*/
1413 0, /*tp_as_sequence*/
1414 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +00001415 (long (*) FPROTO((object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001416 (hashfunc)long_hash, /*tp_hash*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001417};