blob: 1829c3dee72d77e1d61c9a388d10cdde68a5e213 [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 Rossume32e0141992-01-19 16:31:05 +0000555 if (a != NULL) {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000556 a = long_normalize(a);
Guido van Rossume32e0141992-01-19 16:31:05 +0000557 *prem = divrem1(v, d, &d);
558 /* d receives the (unused) remainder */
559 if (*prem == NULL) {
560 DECREF(a);
561 a = NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000562 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000563 }
564 DECREF(v);
565 DECREF(w);
566 return a;
567}
568
569/* Methods */
570
Guido van Rossume32e0141992-01-19 16:31:05 +0000571/* Forward */
Guido van Rossum8b27d921992-03-27 17:27:05 +0000572static void long_dealloc PROTO((object *));
Guido van Rossum8b27d921992-03-27 17:27:05 +0000573static object *long_repr PROTO((object *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000574static int long_compare PROTO((longobject *, longobject *));
Guido van Rossum9bfef441993-03-29 10:43:31 +0000575static long long_hash PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000576
577static object *long_add PROTO((longobject *, longobject *));
578static object *long_sub PROTO((longobject *, longobject *));
579static object *long_mul PROTO((longobject *, longobject *));
580static object *long_div PROTO((longobject *, longobject *));
581static object *long_mod PROTO((longobject *, longobject *));
582static object *long_divmod PROTO((longobject *, longobject *));
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000583static object *long_pow PROTO((longobject *, longobject *, longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000584static object *long_neg PROTO((longobject *));
585static object *long_pos PROTO((longobject *));
586static object *long_abs PROTO((longobject *));
587static int long_nonzero PROTO((longobject *));
588static object *long_invert PROTO((longobject *));
589static object *long_lshift PROTO((longobject *, longobject *));
590static object *long_rshift PROTO((longobject *, longobject *));
591static object *long_and PROTO((longobject *, longobject *));
592static object *long_xor PROTO((longobject *, longobject *));
593static object *long_or PROTO((longobject *, longobject *));
594
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000595static void
596long_dealloc(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000597 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000598{
599 DEL(v);
600}
601
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000602static object *
603long_repr(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000604 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000605{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000606 return long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000607}
608
609static int
610long_compare(a, b)
611 longobject *a, *b;
612{
613 int sign;
614
Guido van Rossumc6913e71991-11-19 20:26:46 +0000615 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000616 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000617 sign = 0;
618 else
619 sign = a->ob_size - b->ob_size;
620 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000621 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000622 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000623 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
624 ;
625 if (i < 0)
626 sign = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000627 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000628 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000629 if (a->ob_size < 0)
630 sign = -sign;
631 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000632 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000633 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000634}
635
Guido van Rossum9bfef441993-03-29 10:43:31 +0000636static long
637long_hash(v)
638 longobject *v;
639{
640 long x;
641 int i, sign;
642
643 /* This is designed so that Python ints and longs with the
644 same value hash to the same value, otherwise comparisons
645 of mapping keys will turn out weird */
646 i = v->ob_size;
647 sign = 1;
648 x = 0;
649 if (i < 0) {
650 sign = -1;
651 i = -(i);
652 }
653 while (--i >= 0) {
654 /* Force a 32-bit circular shift */
655 x = ((x << SHIFT) & ~MASK) | ((x >> (32-SHIFT)) & MASK);
656 x += v->ob_digit[i];
657 }
658 x = x * sign;
659 if (x == -1)
660 x = -2;
661 return x;
662}
663
664
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000665/* Add the absolute values of two long integers. */
666
667static longobject *x_add PROTO((longobject *, longobject *));
668static longobject *
669x_add(a, b)
670 longobject *a, *b;
671{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000672 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000673 longobject *z;
674 int i;
675 digit carry = 0;
676
677 /* Ensure a is the larger of the two: */
678 if (size_a < size_b) {
679 { longobject *temp = a; a = b; b = temp; }
680 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
681 }
682 z = alloclongobject(size_a+1);
683 if (z == NULL)
684 return NULL;
685 for (i = 0; i < size_b; ++i) {
686 carry += a->ob_digit[i] + b->ob_digit[i];
687 z->ob_digit[i] = carry & MASK;
688 /* The following assumes unsigned shifts don't
689 propagate the sign bit. */
690 carry >>= SHIFT;
691 }
692 for (; i < size_a; ++i) {
693 carry += a->ob_digit[i];
694 z->ob_digit[i] = carry & MASK;
695 carry >>= SHIFT;
696 }
697 z->ob_digit[i] = carry;
698 return long_normalize(z);
699}
700
701/* Subtract the absolute values of two integers. */
702
703static longobject *x_sub PROTO((longobject *, longobject *));
704static longobject *
705x_sub(a, b)
706 longobject *a, *b;
707{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000708 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000709 longobject *z;
710 int i;
711 int sign = 1;
712 digit borrow = 0;
713
714 /* Ensure a is the larger of the two: */
715 if (size_a < size_b) {
716 sign = -1;
717 { longobject *temp = a; a = b; b = temp; }
718 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
719 }
720 else if (size_a == size_b) {
721 /* Find highest digit where a and b differ: */
722 i = size_a;
723 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
724 ;
725 if (i < 0)
726 return alloclongobject(0);
727 if (a->ob_digit[i] < b->ob_digit[i]) {
728 sign = -1;
729 { longobject *temp = a; a = b; b = temp; }
730 }
731 size_a = size_b = i+1;
732 }
733 z = alloclongobject(size_a);
734 if (z == NULL)
735 return NULL;
736 for (i = 0; i < size_b; ++i) {
737 /* The following assumes unsigned arithmetic
738 works module 2**N for some N>SHIFT. */
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000739 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000740 z->ob_digit[i] = borrow & MASK;
741 borrow >>= SHIFT;
742 borrow &= 1; /* Keep only one sign bit */
743 }
744 for (; i < size_a; ++i) {
745 borrow = a->ob_digit[i] - borrow;
746 z->ob_digit[i] = borrow & MASK;
747 borrow >>= SHIFT;
748 }
749 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000750 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000751 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000752 return long_normalize(z);
753}
754
755static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000756long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000757 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000758 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000759{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000760 longobject *z;
761
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000762 if (a->ob_size < 0) {
763 if (b->ob_size < 0) {
764 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000765 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000766 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000767 }
768 else
769 z = x_sub(b, a);
770 }
771 else {
772 if (b->ob_size < 0)
773 z = x_sub(a, b);
774 else
775 z = x_add(a, b);
776 }
777 return (object *)z;
778}
779
780static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000781long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000782 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000783 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000784{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000785 longobject *z;
786
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000787 if (a->ob_size < 0) {
788 if (b->ob_size < 0)
789 z = x_sub(a, b);
790 else
791 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000792 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000793 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000794 }
795 else {
796 if (b->ob_size < 0)
797 z = x_add(a, b);
798 else
799 z = x_sub(a, b);
800 }
801 return (object *)z;
802}
803
804static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000805long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000806 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000807 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000808{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000809 int size_a;
810 int size_b;
811 longobject *z;
812 int i;
813
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000814 size_a = ABS(a->ob_size);
815 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000816 z = alloclongobject(size_a + size_b);
817 if (z == NULL)
818 return NULL;
819 for (i = 0; i < z->ob_size; ++i)
820 z->ob_digit[i] = 0;
821 for (i = 0; i < size_a; ++i) {
822 twodigits carry = 0;
823 twodigits f = a->ob_digit[i];
824 int j;
825
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000826 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000827 DECREF(z);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000828 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000829 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000830 for (j = 0; j < size_b; ++j) {
831 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
832 z->ob_digit[i+j] = carry & MASK;
833 carry >>= SHIFT;
834 }
835 for (; carry != 0; ++j) {
836 assert(i+j < z->ob_size);
837 carry += z->ob_digit[i+j];
838 z->ob_digit[i+j] = carry & MASK;
839 carry >>= SHIFT;
840 }
841 }
842 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000843 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000844 if (b->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 return (object *) long_normalize(z);
847}
848
Guido van Rossume32e0141992-01-19 16:31:05 +0000849/* The / and % operators are now defined in terms of divmod().
850 The expression a mod b has the value a - b*floor(a/b).
851 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000852 |a| by |b|, with the sign of a. This is also expressed
853 as a - b*trunc(a/b), if trunc truncates towards zero.
854 Some examples:
855 a b a rem b a mod b
856 13 10 3 3
857 -13 10 -3 7
858 13 -10 3 -7
859 -13 -10 -3 -3
860 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000861 have different signs. We then subtract one from the 'div'
862 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000863
Guido van Rossume32e0141992-01-19 16:31:05 +0000864static int l_divmod PROTO((longobject *, longobject *,
865 longobject **, longobject **));
866static int
867l_divmod(v, w, pdiv, pmod)
868 longobject *v;
869 longobject *w;
870 longobject **pdiv;
871 longobject **pmod;
872{
873 longobject *div, *mod;
874
875 if (long_divrem(v, w, &div, &mod) < 0)
876 return -1;
877 if (mod->ob_size < 0 && w->ob_size > 0 ||
878 mod->ob_size > 0 && w->ob_size < 0) {
879 longobject *temp;
880 longobject *one;
881 temp = (longobject *) long_add(mod, w);
882 DECREF(mod);
883 mod = temp;
884 if (mod == NULL) {
885 DECREF(div);
886 return -1;
887 }
888 one = (longobject *) newlongobject(1L);
889 if (one == NULL ||
890 (temp = (longobject *) long_sub(div, one)) == NULL) {
891 DECREF(mod);
892 DECREF(div);
Guido van Rossume5372401993-03-16 12:15:04 +0000893 XDECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000894 return -1;
895 }
Guido van Rossume5372401993-03-16 12:15:04 +0000896 DECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000897 DECREF(div);
898 div = temp;
899 }
900 *pdiv = div;
901 *pmod = mod;
902 return 0;
903}
904
905static object *
906long_div(v, w)
907 longobject *v;
908 longobject *w;
909{
910 longobject *div, *mod;
911 if (l_divmod(v, w, &div, &mod) < 0)
912 return NULL;
913 DECREF(mod);
914 return (object *)div;
915}
916
917static object *
918long_mod(v, w)
919 longobject *v;
920 longobject *w;
921{
922 longobject *div, *mod;
923 if (l_divmod(v, w, &div, &mod) < 0)
924 return NULL;
925 DECREF(div);
926 return (object *)mod;
927}
928
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000929static object *
930long_divmod(v, w)
931 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000932 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000933{
934 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000935 longobject *div, *mod;
936 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000937 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000938 z = newtupleobject(2);
939 if (z != NULL) {
940 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000941 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000942 }
943 else {
944 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000945 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000946 }
947 return z;
948}
949
950static object *
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000951long_pow(a, b, c)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000952 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000953 longobject *b;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000954 longobject *c;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000955{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000956 longobject *z, *div, *mod;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000957 int size_b, i;
958
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000959 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000960 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000961 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000962 return NULL;
963 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000964 z = (longobject *)newlongobject(1L);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000965 INCREF(a);
966 for (i = 0; i < size_b; ++i) {
967 digit bi = b->ob_digit[i];
968 int j;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000969
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000970 for (j = 0; j < SHIFT; ++j) {
971 longobject *temp;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000972
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000973 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000974 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000975 DECREF(z);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000976 if ((object*)c!=None && temp!=NULL) {
977 l_divmod(temp, c, &div, &mod);
978 XDECREF(div);
979 DECREF(temp);
980 temp = mod;
981 }
982 z = temp;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000983 if (z == NULL)
984 break;
985 }
986 bi >>= 1;
987 if (bi == 0 && i+1 == size_b)
988 break;
Guido van Rossume32e0141992-01-19 16:31:05 +0000989 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000990 DECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000991 if ((object*)c!=None && temp!=NULL) {
992 l_divmod(temp, c, &div, &mod);
993 XDECREF(div);
994 DECREF(temp);
995 temp = mod;
996 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000997 a = temp;
998 if (a == NULL) {
999 DECREF(z);
1000 z = NULL;
1001 break;
1002 }
1003 }
1004 if (a == NULL)
1005 break;
1006 }
1007 XDECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001008 if ((object*)c!=None && z!=NULL) {
1009 l_divmod(z, c, &div, &mod);
1010 XDECREF(div);
1011 DECREF(z);
1012 z=mod;
1013 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001014 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001015}
1016
1017static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001018long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001019 longobject *v;
1020{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001021 /* Implement ~x as -(x+1) */
1022 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +00001023 longobject *w;
1024 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001025 if (w == NULL)
1026 return NULL;
1027 x = (longobject *) long_add(v, w);
1028 DECREF(w);
1029 if (x == NULL)
1030 return NULL;
1031 if (x->ob_size != 0)
1032 x->ob_size = -(x->ob_size);
1033 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001034}
1035
1036static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001037long_pos(v)
1038 longobject *v;
1039{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001040 INCREF(v);
1041 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001042}
1043
1044static object *
1045long_neg(v)
1046 longobject *v;
1047{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001048 longobject *z;
1049 int i, n;
1050 n = ABS(v->ob_size);
1051 if (n == 0) {
1052 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001053 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001054 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001055 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001056 z = alloclongobject(ABS(n));
1057 if (z == NULL)
1058 return NULL;
1059 for (i = 0; i < n; i++)
1060 z->ob_digit[i] = v->ob_digit[i];
1061 z->ob_size = -(v->ob_size);
1062 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001063}
1064
1065static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001066long_abs(v)
1067 longobject *v;
1068{
1069 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001070 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001071 else {
1072 INCREF(v);
1073 return (object *)v;
1074 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001075}
1076
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001077static int
1078long_nonzero(v)
1079 longobject *v;
1080{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001081 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001082}
1083
1084static object *
1085long_rshift(a, b)
1086 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001087 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001088{
1089 longobject *z;
1090 long shiftby;
1091 int newsize, wordshift, loshift, hishift, i, j;
1092 digit lomask, himask;
1093
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001094 if (a->ob_size < 0) {
1095 /* Right shifting negative numbers is harder */
1096 longobject *a1, *a2, *a3;
1097 a1 = (longobject *) long_invert(a);
1098 if (a1 == NULL) return NULL;
1099 a2 = (longobject *) long_rshift(a1, b);
1100 DECREF(a1);
1101 if (a2 == NULL) return NULL;
1102 a3 = (longobject *) long_invert(a2);
1103 DECREF(a2);
1104 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001105 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001106
1107 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001108 if (shiftby == -1L && err_occurred())
1109 return NULL;
1110 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001111 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001112 return NULL;
1113 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001114 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001115 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001116 if (newsize <= 0) {
1117 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001118 return (object *)z;
1119 }
1120 loshift = shiftby % SHIFT;
1121 hishift = SHIFT - loshift;
1122 lomask = ((digit)1 << hishift) - 1;
1123 himask = MASK ^ lomask;
1124 z = alloclongobject(newsize);
1125 if (z == NULL)
1126 return NULL;
1127 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001128 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001129 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1130 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1131 if (i+1 < newsize)
1132 z->ob_digit[i] |=
1133 (a->ob_digit[j+1] << hishift) & himask;
1134 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001135 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001136}
1137
1138static object *
1139long_lshift(a, b)
1140 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001141 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001142{
1143 longobject *z;
1144 long shiftby;
1145 int newsize, wordshift, loshift, hishift, i, j;
1146 digit lomask, himask;
1147
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001148 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001149 if (shiftby == -1L && err_occurred())
1150 return NULL;
1151 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001152 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001153 return NULL;
1154 }
1155 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001156 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001157 return NULL;
1158 }
1159 if (shiftby % SHIFT == 0) {
1160 wordshift = shiftby / SHIFT;
1161 loshift = 0;
1162 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001163 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001164 lomask = MASK;
1165 himask = 0;
1166 }
1167 else {
1168 wordshift = shiftby / SHIFT + 1;
1169 loshift = SHIFT - shiftby%SHIFT;
1170 hishift = shiftby % 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 = ((digit)1 << hishift) - 1;
1173 himask = MASK ^ lomask;
1174 }
1175 z = alloclongobject(newsize);
1176 if (z == NULL)
1177 return NULL;
1178 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001179 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001180 for (i = 0; i < wordshift; i++)
1181 z->ob_digit[i] = 0;
1182 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1183 if (i > 0)
1184 z->ob_digit[i-1] |=
1185 (a->ob_digit[j] << hishift) & himask;
1186 z->ob_digit[i] =
1187 (a->ob_digit[j] >> loshift) & lomask;
1188 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001189 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001190}
1191
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001192
1193/* Bitwise and/xor/or operations */
1194
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001195#define MAX(x, y) ((x) < (y) ? (y) : (x))
1196#define MIN(x, y) ((x) > (y) ? (y) : (x))
1197
Guido van Rossume32e0141992-01-19 16:31:05 +00001198static object *long_bitwise PROTO((longobject *, int, longobject *));
1199static object *
1200long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001201 longobject *a;
1202 int op; /* '&', '|', '^' */
1203 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001204{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001205 digit maska, maskb; /* 0 or MASK */
1206 int negz;
1207 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001208 longobject *z;
1209 int i;
Guido van Rossum8b27d921992-03-27 17:27:05 +00001210 digit diga, digb;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001211 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001212
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001213 if (a->ob_size < 0) {
1214 a = (longobject *) long_invert(a);
1215 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001216 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001217 else {
1218 INCREF(a);
1219 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001220 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001221 if (b->ob_size < 0) {
1222 b = (longobject *) long_invert(b);
1223 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001224 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001225 else {
1226 INCREF(b);
1227 maskb = 0;
1228 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001229
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001230 size_a = a->ob_size;
1231 size_b = b->ob_size;
1232 size_z = MAX(size_a, size_b);
1233 z = alloclongobject(size_z);
1234 if (a == NULL || b == NULL || z == NULL) {
1235 XDECREF(a);
1236 XDECREF(b);
1237 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001238 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001239 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001240
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001241 negz = 0;
1242 switch (op) {
1243 case '^':
1244 if (maska != maskb) {
1245 maska ^= MASK;
1246 negz = -1;
1247 }
1248 break;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001249 case '&':
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001250 if (maska && maskb) {
1251 op = '|';
1252 maska ^= MASK;
1253 maskb ^= MASK;
1254 negz = -1;
1255 }
1256 break;
1257 case '|':
1258 if (maska || maskb) {
1259 op = '&';
1260 maska ^= MASK;
1261 maskb ^= MASK;
1262 negz = -1;
1263 }
1264 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001265 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001266
1267 for (i = 0; i < size_z; ++i) {
1268 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1269 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1270 switch (op) {
1271 case '&': z->ob_digit[i] = diga & digb; break;
1272 case '|': z->ob_digit[i] = diga | digb; break;
1273 case '^': z->ob_digit[i] = diga ^ digb; break;
1274 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001275 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001276
1277 DECREF(a);
1278 DECREF(b);
1279 z = long_normalize(z);
1280 if (negz == 0)
1281 return (object *) z;
1282 v = long_invert(z);
1283 DECREF(z);
1284 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001285}
1286
Guido van Rossumc6913e71991-11-19 20:26:46 +00001287static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001288long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001289 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001290 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001291{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001292 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001293}
1294
1295static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001296long_xor(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_or(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 Rossum23d6f0e1991-05-14 12:06:49 +00001309}
1310
Guido van Rossum234f9421993-06-17 12:35:49 +00001311static int
Guido van Rossume6eefc21992-08-14 12:06:52 +00001312long_coerce(pv, pw)
1313 object **pv;
1314 object **pw;
1315{
1316 if (is_intobject(*pw)) {
1317 *pw = newlongobject(getintvalue(*pw));
1318 INCREF(*pv);
1319 return 0;
1320 }
1321 return 1; /* Can't do it */
1322}
1323
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001324static object *
1325long_int(v)
1326 object *v;
1327{
1328 long x;
1329 x = getlongvalue(v);
1330 if (err_occurred())
1331 return NULL;
1332 return newintobject(x);
1333}
1334
1335static object *
1336long_long(v)
1337 object *v;
1338{
1339 INCREF(v);
1340 return v;
1341}
1342
1343static object *
1344long_float(v)
1345 object *v;
1346{
1347 return newfloatobject(dgetlongvalue(v));
1348}
1349
1350static object *
1351long_oct(v)
1352 object *v;
1353{
1354 return long_format(v, 8);
1355}
1356
1357static object *
1358long_hex(v)
1359 object *v;
1360{
1361 return long_format(v, 16);
1362}
1363
1364
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001365#define UF (unaryfunc)
1366#define BF (binaryfunc)
1367#define TF (ternaryfunc)
1368#define IF (inquiry)
Guido van Rossum8b27d921992-03-27 17:27:05 +00001369
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001370static number_methods long_as_number = {
Guido van Rossum8b27d921992-03-27 17:27:05 +00001371 BF long_add, /*nb_add*/
1372 BF long_sub, /*nb_subtract*/
1373 BF long_mul, /*nb_multiply*/
1374 BF long_div, /*nb_divide*/
1375 BF long_mod, /*nb_remainder*/
1376 BF long_divmod, /*nb_divmod*/
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001377 TF long_pow, /*nb_power*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001378 UF long_neg, /*nb_negative*/
1379 UF long_pos, /*tp_positive*/
1380 UF long_abs, /*tp_absolute*/
1381 IF long_nonzero,/*tp_nonzero*/
1382 UF long_invert, /*nb_invert*/
1383 BF long_lshift, /*nb_lshift*/
1384 BF long_rshift, /*nb_rshift*/
1385 BF long_and, /*nb_and*/
1386 BF long_xor, /*nb_xor*/
1387 BF long_or, /*nb_or*/
Guido van Rossume6eefc21992-08-14 12:06:52 +00001388 (int (*) FPROTO((object **, object **)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001389 (coercion)long_coerce, /*nb_coerce*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001390 UF long_int, /*nb_int*/
1391 UF long_long, /*nb_long*/
1392 UF long_float, /*nb_float*/
1393 UF long_oct, /*nb_oct*/
1394 UF long_hex, /*nb_hex*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001395};
1396
1397typeobject Longtype = {
1398 OB_HEAD_INIT(&Typetype)
1399 0,
1400 "long int",
1401 sizeof(longobject) - sizeof(digit),
1402 sizeof(digit),
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001403 (destructor)long_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001404 0, /*tp_print*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001405 0, /*tp_getattr*/
1406 0, /*tp_setattr*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001407 (int (*) FPROTO((object *, object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001408 (cmpfunc)long_compare, /*tp_compare*/
1409 (reprfunc)long_repr, /*tp_repr*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001410 &long_as_number,/*tp_as_number*/
1411 0, /*tp_as_sequence*/
1412 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +00001413 (long (*) FPROTO((object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001414 (hashfunc)long_hash, /*tp_hash*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001415};