blob: 82a74c0a12a0e38d7535b741159b49afccd2ae82 [file] [log] [blame]
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001/***********************************************************
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00002Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Guido van Rossum34679b71993-01-26 13:33:44 +00003Amsterdam, The 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 *));
573static int long_print PROTO((object *, FILE *, int));
574static object *long_repr PROTO((object *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000575static int long_compare PROTO((longobject *, longobject *));
Guido van Rossum9bfef441993-03-29 10:43:31 +0000576static long long_hash PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000577
578static object *long_add PROTO((longobject *, longobject *));
579static object *long_sub PROTO((longobject *, longobject *));
580static object *long_mul PROTO((longobject *, longobject *));
581static object *long_div PROTO((longobject *, longobject *));
582static object *long_mod PROTO((longobject *, longobject *));
583static object *long_divmod PROTO((longobject *, longobject *));
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000584static object *long_pow PROTO((longobject *, longobject *, longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000585static object *long_neg PROTO((longobject *));
586static object *long_pos PROTO((longobject *));
587static object *long_abs PROTO((longobject *));
588static int long_nonzero PROTO((longobject *));
589static object *long_invert PROTO((longobject *));
590static object *long_lshift PROTO((longobject *, longobject *));
591static object *long_rshift PROTO((longobject *, longobject *));
592static object *long_and PROTO((longobject *, longobject *));
593static object *long_xor PROTO((longobject *, longobject *));
594static object *long_or PROTO((longobject *, longobject *));
595
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000596static void
597long_dealloc(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000598 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000599{
600 DEL(v);
601}
602
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000603static object *
604long_repr(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000605 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000606{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000607 return long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000608}
609
610static int
611long_compare(a, b)
612 longobject *a, *b;
613{
614 int sign;
615
Guido van Rossumc6913e71991-11-19 20:26:46 +0000616 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000617 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000618 sign = 0;
619 else
620 sign = a->ob_size - b->ob_size;
621 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000622 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000623 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000624 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
625 ;
626 if (i < 0)
627 sign = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000628 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000629 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000630 if (a->ob_size < 0)
631 sign = -sign;
632 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000633 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000634 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000635}
636
Guido van Rossum9bfef441993-03-29 10:43:31 +0000637static long
638long_hash(v)
639 longobject *v;
640{
641 long x;
642 int i, sign;
643
644 /* This is designed so that Python ints and longs with the
645 same value hash to the same value, otherwise comparisons
646 of mapping keys will turn out weird */
647 i = v->ob_size;
648 sign = 1;
649 x = 0;
650 if (i < 0) {
651 sign = -1;
652 i = -(i);
653 }
654 while (--i >= 0) {
655 /* Force a 32-bit circular shift */
656 x = ((x << SHIFT) & ~MASK) | ((x >> (32-SHIFT)) & MASK);
657 x += v->ob_digit[i];
658 }
659 x = x * sign;
660 if (x == -1)
661 x = -2;
662 return x;
663}
664
665
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000666/* Add the absolute values of two long integers. */
667
668static longobject *x_add PROTO((longobject *, longobject *));
669static longobject *
670x_add(a, b)
671 longobject *a, *b;
672{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000673 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000674 longobject *z;
675 int i;
676 digit carry = 0;
677
678 /* Ensure a is the larger of the two: */
679 if (size_a < size_b) {
680 { longobject *temp = a; a = b; b = temp; }
681 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
682 }
683 z = alloclongobject(size_a+1);
684 if (z == NULL)
685 return NULL;
686 for (i = 0; i < size_b; ++i) {
687 carry += a->ob_digit[i] + b->ob_digit[i];
688 z->ob_digit[i] = carry & MASK;
689 /* The following assumes unsigned shifts don't
690 propagate the sign bit. */
691 carry >>= SHIFT;
692 }
693 for (; i < size_a; ++i) {
694 carry += a->ob_digit[i];
695 z->ob_digit[i] = carry & MASK;
696 carry >>= SHIFT;
697 }
698 z->ob_digit[i] = carry;
699 return long_normalize(z);
700}
701
702/* Subtract the absolute values of two integers. */
703
704static longobject *x_sub PROTO((longobject *, longobject *));
705static longobject *
706x_sub(a, b)
707 longobject *a, *b;
708{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000709 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000710 longobject *z;
711 int i;
712 int sign = 1;
713 digit borrow = 0;
714
715 /* Ensure a is the larger of the two: */
716 if (size_a < size_b) {
717 sign = -1;
718 { longobject *temp = a; a = b; b = temp; }
719 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
720 }
721 else if (size_a == size_b) {
722 /* Find highest digit where a and b differ: */
723 i = size_a;
724 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
725 ;
726 if (i < 0)
727 return alloclongobject(0);
728 if (a->ob_digit[i] < b->ob_digit[i]) {
729 sign = -1;
730 { longobject *temp = a; a = b; b = temp; }
731 }
732 size_a = size_b = i+1;
733 }
734 z = alloclongobject(size_a);
735 if (z == NULL)
736 return NULL;
737 for (i = 0; i < size_b; ++i) {
738 /* The following assumes unsigned arithmetic
739 works module 2**N for some N>SHIFT. */
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000740 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000741 z->ob_digit[i] = borrow & MASK;
742 borrow >>= SHIFT;
743 borrow &= 1; /* Keep only one sign bit */
744 }
745 for (; i < size_a; ++i) {
746 borrow = a->ob_digit[i] - borrow;
747 z->ob_digit[i] = borrow & MASK;
748 borrow >>= SHIFT;
749 }
750 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000751 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000752 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000753 return long_normalize(z);
754}
755
756static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000757long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000758 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000759 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000760{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000761 longobject *z;
762
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000763 if (a->ob_size < 0) {
764 if (b->ob_size < 0) {
765 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000766 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000767 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000768 }
769 else
770 z = x_sub(b, a);
771 }
772 else {
773 if (b->ob_size < 0)
774 z = x_sub(a, b);
775 else
776 z = x_add(a, b);
777 }
778 return (object *)z;
779}
780
781static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000782long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000783 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000784 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000785{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000786 longobject *z;
787
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000788 if (a->ob_size < 0) {
789 if (b->ob_size < 0)
790 z = x_sub(a, b);
791 else
792 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000793 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000794 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000795 }
796 else {
797 if (b->ob_size < 0)
798 z = x_add(a, b);
799 else
800 z = x_sub(a, b);
801 }
802 return (object *)z;
803}
804
805static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000806long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000807 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000808 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000809{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000810 int size_a;
811 int size_b;
812 longobject *z;
813 int i;
814
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000815 size_a = ABS(a->ob_size);
816 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000817 z = alloclongobject(size_a + size_b);
818 if (z == NULL)
819 return NULL;
820 for (i = 0; i < z->ob_size; ++i)
821 z->ob_digit[i] = 0;
822 for (i = 0; i < size_a; ++i) {
823 twodigits carry = 0;
824 twodigits f = a->ob_digit[i];
825 int j;
826
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000827 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000828 DECREF(z);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000829 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000830 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000831 for (j = 0; j < size_b; ++j) {
832 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
833 z->ob_digit[i+j] = carry & MASK;
834 carry >>= SHIFT;
835 }
836 for (; carry != 0; ++j) {
837 assert(i+j < z->ob_size);
838 carry += z->ob_digit[i+j];
839 z->ob_digit[i+j] = carry & MASK;
840 carry >>= SHIFT;
841 }
842 }
843 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000844 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000845 if (b->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000846 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000847 return (object *) long_normalize(z);
848}
849
Guido van Rossume32e0141992-01-19 16:31:05 +0000850/* The / and % operators are now defined in terms of divmod().
851 The expression a mod b has the value a - b*floor(a/b).
852 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000853 |a| by |b|, with the sign of a. This is also expressed
854 as a - b*trunc(a/b), if trunc truncates towards zero.
855 Some examples:
856 a b a rem b a mod b
857 13 10 3 3
858 -13 10 -3 7
859 13 -10 3 -7
860 -13 -10 -3 -3
861 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000862 have different signs. We then subtract one from the 'div'
863 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000864
Guido van Rossume32e0141992-01-19 16:31:05 +0000865static int l_divmod PROTO((longobject *, longobject *,
866 longobject **, longobject **));
867static int
868l_divmod(v, w, pdiv, pmod)
869 longobject *v;
870 longobject *w;
871 longobject **pdiv;
872 longobject **pmod;
873{
874 longobject *div, *mod;
875
876 if (long_divrem(v, w, &div, &mod) < 0)
877 return -1;
878 if (mod->ob_size < 0 && w->ob_size > 0 ||
879 mod->ob_size > 0 && w->ob_size < 0) {
880 longobject *temp;
881 longobject *one;
882 temp = (longobject *) long_add(mod, w);
883 DECREF(mod);
884 mod = temp;
885 if (mod == NULL) {
886 DECREF(div);
887 return -1;
888 }
889 one = (longobject *) newlongobject(1L);
890 if (one == NULL ||
891 (temp = (longobject *) long_sub(div, one)) == NULL) {
892 DECREF(mod);
893 DECREF(div);
Guido van Rossume5372401993-03-16 12:15:04 +0000894 XDECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000895 return -1;
896 }
Guido van Rossume5372401993-03-16 12:15:04 +0000897 DECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000898 DECREF(div);
899 div = temp;
900 }
901 *pdiv = div;
902 *pmod = mod;
903 return 0;
904}
905
906static object *
907long_div(v, w)
908 longobject *v;
909 longobject *w;
910{
911 longobject *div, *mod;
912 if (l_divmod(v, w, &div, &mod) < 0)
913 return NULL;
914 DECREF(mod);
915 return (object *)div;
916}
917
918static object *
919long_mod(v, w)
920 longobject *v;
921 longobject *w;
922{
923 longobject *div, *mod;
924 if (l_divmod(v, w, &div, &mod) < 0)
925 return NULL;
926 DECREF(div);
927 return (object *)mod;
928}
929
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000930static object *
931long_divmod(v, w)
932 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000933 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000934{
935 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000936 longobject *div, *mod;
937 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000938 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000939 z = newtupleobject(2);
940 if (z != NULL) {
941 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000942 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000943 }
944 else {
945 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000946 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000947 }
948 return z;
949}
950
951static object *
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000952long_pow(a, b, c)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000953 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000954 longobject *b;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000955 longobject *c;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000956{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000957 longobject *z, *div, *mod;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000958 int size_b, i;
959
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000960 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000961 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000962 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000963 return NULL;
964 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000965 z = (longobject *)newlongobject(1L);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000966 INCREF(a);
967 for (i = 0; i < size_b; ++i) {
968 digit bi = b->ob_digit[i];
969 int j;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000970
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000971 for (j = 0; j < SHIFT; ++j) {
972 longobject *temp;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000973
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000974 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000975 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000976 DECREF(z);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000977 if ((object*)c!=None && temp!=NULL) {
978 l_divmod(temp, c, &div, &mod);
979 XDECREF(div);
980 DECREF(temp);
981 temp = mod;
982 }
983 z = temp;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000984 if (z == NULL)
985 break;
986 }
987 bi >>= 1;
988 if (bi == 0 && i+1 == size_b)
989 break;
Guido van Rossume32e0141992-01-19 16:31:05 +0000990 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000991 DECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000992 if ((object*)c!=None && temp!=NULL) {
993 l_divmod(temp, c, &div, &mod);
994 XDECREF(div);
995 DECREF(temp);
996 temp = mod;
997 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000998 a = temp;
999 if (a == NULL) {
1000 DECREF(z);
1001 z = NULL;
1002 break;
1003 }
1004 }
1005 if (a == NULL)
1006 break;
1007 }
1008 XDECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001009 if ((object*)c!=None && z!=NULL) {
1010 l_divmod(z, c, &div, &mod);
1011 XDECREF(div);
1012 DECREF(z);
1013 z=mod;
1014 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001015 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001016}
1017
1018static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001019long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001020 longobject *v;
1021{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001022 /* Implement ~x as -(x+1) */
1023 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +00001024 longobject *w;
1025 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001026 if (w == NULL)
1027 return NULL;
1028 x = (longobject *) long_add(v, w);
1029 DECREF(w);
1030 if (x == NULL)
1031 return NULL;
1032 if (x->ob_size != 0)
1033 x->ob_size = -(x->ob_size);
1034 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001035}
1036
1037static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001038long_pos(v)
1039 longobject *v;
1040{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001041 INCREF(v);
1042 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001043}
1044
1045static object *
1046long_neg(v)
1047 longobject *v;
1048{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001049 longobject *z;
1050 int i, n;
1051 n = ABS(v->ob_size);
1052 if (n == 0) {
1053 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001054 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001055 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001056 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001057 z = alloclongobject(ABS(n));
1058 if (z == NULL)
1059 return NULL;
1060 for (i = 0; i < n; i++)
1061 z->ob_digit[i] = v->ob_digit[i];
1062 z->ob_size = -(v->ob_size);
1063 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001064}
1065
1066static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001067long_abs(v)
1068 longobject *v;
1069{
1070 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001071 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001072 else {
1073 INCREF(v);
1074 return (object *)v;
1075 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001076}
1077
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001078static int
1079long_nonzero(v)
1080 longobject *v;
1081{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001082 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001083}
1084
1085static object *
1086long_rshift(a, b)
1087 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001088 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001089{
1090 longobject *z;
1091 long shiftby;
1092 int newsize, wordshift, loshift, hishift, i, j;
1093 digit lomask, himask;
1094
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001095 if (a->ob_size < 0) {
1096 /* Right shifting negative numbers is harder */
1097 longobject *a1, *a2, *a3;
1098 a1 = (longobject *) long_invert(a);
1099 if (a1 == NULL) return NULL;
1100 a2 = (longobject *) long_rshift(a1, b);
1101 DECREF(a1);
1102 if (a2 == NULL) return NULL;
1103 a3 = (longobject *) long_invert(a2);
1104 DECREF(a2);
1105 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001106 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001107
1108 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001109 if (shiftby == -1L && err_occurred())
1110 return NULL;
1111 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001112 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001113 return NULL;
1114 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001115 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001116 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001117 if (newsize <= 0) {
1118 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001119 return (object *)z;
1120 }
1121 loshift = shiftby % SHIFT;
1122 hishift = SHIFT - loshift;
1123 lomask = ((digit)1 << hishift) - 1;
1124 himask = MASK ^ lomask;
1125 z = alloclongobject(newsize);
1126 if (z == NULL)
1127 return NULL;
1128 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001129 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001130 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1131 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1132 if (i+1 < newsize)
1133 z->ob_digit[i] |=
1134 (a->ob_digit[j+1] << hishift) & himask;
1135 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001136 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001137}
1138
1139static object *
1140long_lshift(a, b)
1141 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001142 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001143{
1144 longobject *z;
1145 long shiftby;
1146 int newsize, wordshift, loshift, hishift, i, j;
1147 digit lomask, himask;
1148
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001149 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001150 if (shiftby == -1L && err_occurred())
1151 return NULL;
1152 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001153 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001154 return NULL;
1155 }
1156 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001157 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001158 return NULL;
1159 }
1160 if (shiftby % SHIFT == 0) {
1161 wordshift = shiftby / SHIFT;
1162 loshift = 0;
1163 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001164 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001165 lomask = MASK;
1166 himask = 0;
1167 }
1168 else {
1169 wordshift = shiftby / SHIFT + 1;
1170 loshift = SHIFT - shiftby%SHIFT;
1171 hishift = shiftby % SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001172 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001173 lomask = ((digit)1 << hishift) - 1;
1174 himask = MASK ^ lomask;
1175 }
1176 z = alloclongobject(newsize);
1177 if (z == NULL)
1178 return NULL;
1179 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001180 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001181 for (i = 0; i < wordshift; i++)
1182 z->ob_digit[i] = 0;
1183 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1184 if (i > 0)
1185 z->ob_digit[i-1] |=
1186 (a->ob_digit[j] << hishift) & himask;
1187 z->ob_digit[i] =
1188 (a->ob_digit[j] >> loshift) & lomask;
1189 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001190 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001191}
1192
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001193
1194/* Bitwise and/xor/or operations */
1195
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001196#define MAX(x, y) ((x) < (y) ? (y) : (x))
1197#define MIN(x, y) ((x) > (y) ? (y) : (x))
1198
Guido van Rossume32e0141992-01-19 16:31:05 +00001199static object *long_bitwise PROTO((longobject *, int, longobject *));
1200static object *
1201long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001202 longobject *a;
1203 int op; /* '&', '|', '^' */
1204 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001205{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001206 digit maska, maskb; /* 0 or MASK */
1207 int negz;
1208 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001209 longobject *z;
1210 int i;
Guido van Rossum8b27d921992-03-27 17:27:05 +00001211 digit diga, digb;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001212 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001213
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001214 if (a->ob_size < 0) {
1215 a = (longobject *) long_invert(a);
1216 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001217 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001218 else {
1219 INCREF(a);
1220 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001221 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001222 if (b->ob_size < 0) {
1223 b = (longobject *) long_invert(b);
1224 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001225 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001226 else {
1227 INCREF(b);
1228 maskb = 0;
1229 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001230
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001231 size_a = a->ob_size;
1232 size_b = b->ob_size;
1233 size_z = MAX(size_a, size_b);
1234 z = alloclongobject(size_z);
1235 if (a == NULL || b == NULL || z == NULL) {
1236 XDECREF(a);
1237 XDECREF(b);
1238 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001239 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001240 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001241
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001242 negz = 0;
1243 switch (op) {
1244 case '^':
1245 if (maska != maskb) {
1246 maska ^= MASK;
1247 negz = -1;
1248 }
1249 break;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001250 case '&':
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001251 if (maska && maskb) {
1252 op = '|';
1253 maska ^= MASK;
1254 maskb ^= MASK;
1255 negz = -1;
1256 }
1257 break;
1258 case '|':
1259 if (maska || maskb) {
1260 op = '&';
1261 maska ^= MASK;
1262 maskb ^= MASK;
1263 negz = -1;
1264 }
1265 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001266 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001267
1268 for (i = 0; i < size_z; ++i) {
1269 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1270 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1271 switch (op) {
1272 case '&': z->ob_digit[i] = diga & digb; break;
1273 case '|': z->ob_digit[i] = diga | digb; break;
1274 case '^': z->ob_digit[i] = diga ^ digb; break;
1275 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001276 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001277
1278 DECREF(a);
1279 DECREF(b);
1280 z = long_normalize(z);
1281 if (negz == 0)
1282 return (object *) z;
1283 v = long_invert(z);
1284 DECREF(z);
1285 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001286}
1287
Guido van Rossumc6913e71991-11-19 20:26:46 +00001288static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001289long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001290 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001291 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001292{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001293 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001294}
1295
1296static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001297long_xor(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001298 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001299 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001300{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001301 return long_bitwise(a, '^', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001302}
1303
1304static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001305long_or(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001306 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001307 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001308{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001309 return long_bitwise(a, '|', b);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001310}
1311
Guido van Rossum234f9421993-06-17 12:35:49 +00001312static int
Guido van Rossume6eefc21992-08-14 12:06:52 +00001313long_coerce(pv, pw)
1314 object **pv;
1315 object **pw;
1316{
1317 if (is_intobject(*pw)) {
1318 *pw = newlongobject(getintvalue(*pw));
1319 INCREF(*pv);
1320 return 0;
1321 }
1322 return 1; /* Can't do it */
1323}
1324
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001325static object *
1326long_int(v)
1327 object *v;
1328{
1329 long x;
1330 x = getlongvalue(v);
1331 if (err_occurred())
1332 return NULL;
1333 return newintobject(x);
1334}
1335
1336static object *
1337long_long(v)
1338 object *v;
1339{
1340 INCREF(v);
1341 return v;
1342}
1343
1344static object *
1345long_float(v)
1346 object *v;
1347{
1348 return newfloatobject(dgetlongvalue(v));
1349}
1350
1351static object *
1352long_oct(v)
1353 object *v;
1354{
1355 return long_format(v, 8);
1356}
1357
1358static object *
1359long_hex(v)
1360 object *v;
1361{
1362 return long_format(v, 16);
1363}
1364
1365
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001366#define UF (unaryfunc)
1367#define BF (binaryfunc)
1368#define TF (ternaryfunc)
1369#define IF (inquiry)
Guido van Rossum8b27d921992-03-27 17:27:05 +00001370
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001371static number_methods long_as_number = {
Guido van Rossum8b27d921992-03-27 17:27:05 +00001372 BF long_add, /*nb_add*/
1373 BF long_sub, /*nb_subtract*/
1374 BF long_mul, /*nb_multiply*/
1375 BF long_div, /*nb_divide*/
1376 BF long_mod, /*nb_remainder*/
1377 BF long_divmod, /*nb_divmod*/
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001378 TF long_pow, /*nb_power*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001379 UF long_neg, /*nb_negative*/
1380 UF long_pos, /*tp_positive*/
1381 UF long_abs, /*tp_absolute*/
1382 IF long_nonzero,/*tp_nonzero*/
1383 UF long_invert, /*nb_invert*/
1384 BF long_lshift, /*nb_lshift*/
1385 BF long_rshift, /*nb_rshift*/
1386 BF long_and, /*nb_and*/
1387 BF long_xor, /*nb_xor*/
1388 BF long_or, /*nb_or*/
Guido van Rossume6eefc21992-08-14 12:06:52 +00001389 (int (*) FPROTO((object **, object **)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001390 (coercion)long_coerce, /*nb_coerce*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001391 UF long_int, /*nb_int*/
1392 UF long_long, /*nb_long*/
1393 UF long_float, /*nb_float*/
1394 UF long_oct, /*nb_oct*/
1395 UF long_hex, /*nb_hex*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001396};
1397
1398typeobject Longtype = {
1399 OB_HEAD_INIT(&Typetype)
1400 0,
1401 "long int",
1402 sizeof(longobject) - sizeof(digit),
1403 sizeof(digit),
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001404 (destructor)long_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001405 0, /*tp_print*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001406 0, /*tp_getattr*/
1407 0, /*tp_setattr*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001408 (int (*) FPROTO((object *, object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001409 (cmpfunc)long_compare, /*tp_compare*/
1410 (reprfunc)long_repr, /*tp_repr*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001411 &long_as_number,/*tp_as_number*/
1412 0, /*tp_as_sequence*/
1413 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +00001414 (long (*) FPROTO((object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001415 (hashfunc)long_hash, /*tp_hash*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001416};