blob: b9935b033833b121e6cf55a345e24d578b0076d8 [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
Guido van Rossum3535f6e1995-01-17 16:34:13 +0000353#if 0
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000354/* Convert a string to a long int object, in a given base.
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000355 Base zero implies a default depending on the number.
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000356 External linkage: used in compile.c and stropmodule.c. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000357
358object *
359long_scan(str, base)
360 char *str;
361 int base;
362{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000363 return long_escan(str, (char **)NULL, base);
364}
Guido van Rossum3535f6e1995-01-17 16:34:13 +0000365#endif
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000366
367object *
368long_escan(str, pend, base)
369 char *str;
370 char **pend;
371 int base;
372{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000373 int sign = 1;
374 longobject *z;
375
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000376 if (base != 0 && base < 2 || base > 36) {
377 err_setstr(ValueError, "invalid base for long literal");
378 return NULL;
379 }
380 while (*str != '\0' && isspace(*str))
381 str++;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000382 if (*str == '+')
383 ++str;
384 else if (*str == '-') {
385 ++str;
386 sign = -1;
387 }
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000388 while (*str != '\0' && isspace(*str))
389 str++;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000390 if (base == 0) {
391 if (str[0] != '0')
392 base = 10;
393 else if (str[1] == 'x' || str[1] == 'X')
394 base = 16;
395 else
396 base = 8;
397 }
398 if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
399 str += 2;
400 z = alloclongobject(0);
401 for ( ; z != NULL; ++str) {
402 int k = -1;
403 longobject *temp;
404
405 if (*str <= '9')
406 k = *str - '0';
407 else if (*str >= 'a')
408 k = *str - 'a' + 10;
409 else if (*str >= 'A')
410 k = *str - 'A' + 10;
411 if (k < 0 || k >= base)
412 break;
413 temp = muladd1(z, (digit)base, (digit)k);
414 DECREF(z);
415 z = temp;
416 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000417 if (sign < 0 && z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000418 z->ob_size = -(z->ob_size);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000419 if (pend)
420 *pend = str;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000421 return (object *) z;
422}
423
424static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
Guido van Rossumc6913e71991-11-19 20:26:46 +0000425static object *long_pos PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000426static long_divrem PROTO((longobject *, longobject *,
427 longobject **, longobject **));
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000428
429/* Long division with remainder, top-level routine */
430
Guido van Rossume32e0141992-01-19 16:31:05 +0000431static int
432long_divrem(a, b, pdiv, prem)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000433 longobject *a, *b;
Guido van Rossume32e0141992-01-19 16:31:05 +0000434 longobject **pdiv;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000435 longobject **prem;
436{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000437 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000438 longobject *z;
439
440 if (size_b == 0) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000441 err_setstr(ZeroDivisionError, "long division or modulo");
442 return -1;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000443 }
444 if (size_a < size_b ||
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000445 size_a == size_b &&
446 a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000447 /* |a| < |b|. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000448 *pdiv = alloclongobject(0);
449 INCREF(a);
450 *prem = (longobject *) a;
451 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000452 }
453 if (size_b == 1) {
454 digit rem = 0;
455 z = divrem1(a, b->ob_digit[0], &rem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000456 if (z == NULL)
457 return -1;
458 *prem = (longobject *) newlongobject((long)rem);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000459 }
Guido van Rossume32e0141992-01-19 16:31:05 +0000460 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000461 z = x_divrem(a, b, prem);
Guido van Rossume32e0141992-01-19 16:31:05 +0000462 if (z == NULL)
463 return -1;
464 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000465 /* Set the signs.
466 The quotient z has the sign of a*b;
467 the remainder r has the sign of a,
468 so a = b*z + r. */
Guido van Rossume32e0141992-01-19 16:31:05 +0000469 if ((a->ob_size < 0) != (b->ob_size < 0))
470 z->ob_size = -(z->ob_size);
471 if (a->ob_size < 0 && (*prem)->ob_size != 0)
472 (*prem)->ob_size = -((*prem)->ob_size);
473 *pdiv = z;
474 return 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000475}
476
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000477/* Unsigned long division with remainder -- the algorithm */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000478
479static longobject *
480x_divrem(v1, w1, prem)
481 longobject *v1, *w1;
482 longobject **prem;
483{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000484 int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000485 digit d = (twodigits)BASE / (w1->ob_digit[size_w-1] + 1);
486 longobject *v = mul1(v1, d);
487 longobject *w = mul1(w1, d);
488 longobject *a;
489 int j, k;
490
491 if (v == NULL || w == NULL) {
492 XDECREF(v);
493 XDECREF(w);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000494 return NULL;
495 }
496
497 assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000498 assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000499 assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000500
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000501 size_v = ABS(v->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000502 a = alloclongobject(size_v - size_w + 1);
503
504 for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
505 digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
506 twodigits q;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000507 stwodigits carry = 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000508 int i;
509
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000510 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000511 DECREF(a);
512 a = NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000513 break;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000514 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000515 if (vj == w->ob_digit[size_w-1])
516 q = MASK;
517 else
518 q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
519 w->ob_digit[size_w-1];
520
521 while (w->ob_digit[size_w-2]*q >
522 ((
523 ((twodigits)vj << SHIFT)
524 + v->ob_digit[j-1]
525 - q*w->ob_digit[size_w-1]
526 ) << SHIFT)
527 + v->ob_digit[j-2])
528 --q;
529
530 for (i = 0; i < size_w && i+k < size_v; ++i) {
531 twodigits z = w->ob_digit[i] * q;
532 digit zz = z >> SHIFT;
533 carry += v->ob_digit[i+k] - z + ((twodigits)zz << SHIFT);
534 v->ob_digit[i+k] = carry & MASK;
535 carry = (carry >> SHIFT) - zz;
536 }
537
538 if (i+k < size_v) {
539 carry += v->ob_digit[i+k];
540 v->ob_digit[i+k] = 0;
541 }
542
543 if (carry == 0)
544 a->ob_digit[k] = q;
545 else {
546 assert(carry == -1);
547 a->ob_digit[k] = q-1;
548 carry = 0;
549 for (i = 0; i < size_w && i+k < size_v; ++i) {
550 carry += v->ob_digit[i+k] + w->ob_digit[i];
551 v->ob_digit[i+k] = carry & MASK;
552 carry >>= SHIFT;
553 }
554 }
555 } /* for j, k */
556
Guido van Rossumc206c761995-01-10 15:23:19 +0000557 if (a == NULL)
558 *prem = NULL;
559 else {
Guido van Rossumc6913e71991-11-19 20:26:46 +0000560 a = long_normalize(a);
Guido van Rossume32e0141992-01-19 16:31:05 +0000561 *prem = divrem1(v, d, &d);
562 /* d receives the (unused) remainder */
563 if (*prem == NULL) {
564 DECREF(a);
565 a = NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +0000566 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000567 }
568 DECREF(v);
569 DECREF(w);
570 return a;
571}
572
573/* Methods */
574
Guido van Rossume32e0141992-01-19 16:31:05 +0000575/* Forward */
Guido van Rossum8b27d921992-03-27 17:27:05 +0000576static void long_dealloc PROTO((object *));
Guido van Rossum8b27d921992-03-27 17:27:05 +0000577static object *long_repr PROTO((object *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000578static int long_compare PROTO((longobject *, longobject *));
Guido van Rossum9bfef441993-03-29 10:43:31 +0000579static long long_hash PROTO((longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000580
581static object *long_add PROTO((longobject *, longobject *));
582static object *long_sub PROTO((longobject *, longobject *));
583static object *long_mul PROTO((longobject *, longobject *));
584static object *long_div PROTO((longobject *, longobject *));
585static object *long_mod PROTO((longobject *, longobject *));
586static object *long_divmod PROTO((longobject *, longobject *));
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000587static object *long_pow PROTO((longobject *, longobject *, longobject *));
Guido van Rossume32e0141992-01-19 16:31:05 +0000588static object *long_neg PROTO((longobject *));
589static object *long_pos PROTO((longobject *));
590static object *long_abs PROTO((longobject *));
591static int long_nonzero PROTO((longobject *));
592static object *long_invert PROTO((longobject *));
593static object *long_lshift PROTO((longobject *, longobject *));
594static object *long_rshift PROTO((longobject *, longobject *));
595static object *long_and PROTO((longobject *, longobject *));
596static object *long_xor PROTO((longobject *, longobject *));
597static object *long_or PROTO((longobject *, longobject *));
598
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000599static void
600long_dealloc(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000601 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000602{
603 DEL(v);
604}
605
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000606static object *
607long_repr(v)
Guido van Rossum8b27d921992-03-27 17:27:05 +0000608 object *v;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000609{
Guido van Rossum8b27d921992-03-27 17:27:05 +0000610 return long_format(v, 10);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000611}
612
613static int
614long_compare(a, b)
615 longobject *a, *b;
616{
617 int sign;
618
Guido van Rossumc6913e71991-11-19 20:26:46 +0000619 if (a->ob_size != b->ob_size) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000620 if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
Guido van Rossumc6913e71991-11-19 20:26:46 +0000621 sign = 0;
622 else
623 sign = a->ob_size - b->ob_size;
624 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000625 else {
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000626 int i = ABS(a->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000627 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
628 ;
629 if (i < 0)
630 sign = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000631 else {
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000632 sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000633 if (a->ob_size < 0)
634 sign = -sign;
635 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000636 }
Guido van Rossumc6913e71991-11-19 20:26:46 +0000637 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000638}
639
Guido van Rossum9bfef441993-03-29 10:43:31 +0000640static long
641long_hash(v)
642 longobject *v;
643{
644 long x;
645 int i, sign;
646
647 /* This is designed so that Python ints and longs with the
648 same value hash to the same value, otherwise comparisons
649 of mapping keys will turn out weird */
650 i = v->ob_size;
651 sign = 1;
652 x = 0;
653 if (i < 0) {
654 sign = -1;
655 i = -(i);
656 }
657 while (--i >= 0) {
658 /* Force a 32-bit circular shift */
659 x = ((x << SHIFT) & ~MASK) | ((x >> (32-SHIFT)) & MASK);
660 x += v->ob_digit[i];
661 }
662 x = x * sign;
663 if (x == -1)
664 x = -2;
665 return x;
666}
667
668
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000669/* Add the absolute values of two long integers. */
670
671static longobject *x_add PROTO((longobject *, longobject *));
672static longobject *
673x_add(a, b)
674 longobject *a, *b;
675{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000676 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000677 longobject *z;
678 int i;
679 digit carry = 0;
680
681 /* Ensure a is the larger of the two: */
682 if (size_a < size_b) {
683 { longobject *temp = a; a = b; b = temp; }
684 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
685 }
686 z = alloclongobject(size_a+1);
687 if (z == NULL)
688 return NULL;
689 for (i = 0; i < size_b; ++i) {
690 carry += a->ob_digit[i] + b->ob_digit[i];
691 z->ob_digit[i] = carry & MASK;
692 /* The following assumes unsigned shifts don't
693 propagate the sign bit. */
694 carry >>= SHIFT;
695 }
696 for (; i < size_a; ++i) {
697 carry += a->ob_digit[i];
698 z->ob_digit[i] = carry & MASK;
699 carry >>= SHIFT;
700 }
701 z->ob_digit[i] = carry;
702 return long_normalize(z);
703}
704
705/* Subtract the absolute values of two integers. */
706
707static longobject *x_sub PROTO((longobject *, longobject *));
708static longobject *
709x_sub(a, b)
710 longobject *a, *b;
711{
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000712 int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000713 longobject *z;
714 int i;
715 int sign = 1;
716 digit borrow = 0;
717
718 /* Ensure a is the larger of the two: */
719 if (size_a < size_b) {
720 sign = -1;
721 { longobject *temp = a; a = b; b = temp; }
722 { int size_temp = size_a; size_a = size_b; size_b = size_temp; }
723 }
724 else if (size_a == size_b) {
725 /* Find highest digit where a and b differ: */
726 i = size_a;
727 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
728 ;
729 if (i < 0)
730 return alloclongobject(0);
731 if (a->ob_digit[i] < b->ob_digit[i]) {
732 sign = -1;
733 { longobject *temp = a; a = b; b = temp; }
734 }
735 size_a = size_b = i+1;
736 }
737 z = alloclongobject(size_a);
738 if (z == NULL)
739 return NULL;
740 for (i = 0; i < size_b; ++i) {
741 /* The following assumes unsigned arithmetic
742 works module 2**N for some N>SHIFT. */
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000743 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000744 z->ob_digit[i] = borrow & MASK;
745 borrow >>= SHIFT;
746 borrow &= 1; /* Keep only one sign bit */
747 }
748 for (; i < size_a; ++i) {
749 borrow = a->ob_digit[i] - borrow;
750 z->ob_digit[i] = borrow & MASK;
751 borrow >>= SHIFT;
752 }
753 assert(borrow == 0);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000754 if (sign < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000755 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000756 return long_normalize(z);
757}
758
759static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000760long_add(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000761 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000762 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000763{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000764 longobject *z;
765
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000766 if (a->ob_size < 0) {
767 if (b->ob_size < 0) {
768 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000769 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000770 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000771 }
772 else
773 z = x_sub(b, a);
774 }
775 else {
776 if (b->ob_size < 0)
777 z = x_sub(a, b);
778 else
779 z = x_add(a, b);
780 }
781 return (object *)z;
782}
783
784static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000785long_sub(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000786 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000787 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000788{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000789 longobject *z;
790
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000791 if (a->ob_size < 0) {
792 if (b->ob_size < 0)
793 z = x_sub(a, b);
794 else
795 z = x_add(a, b);
Guido van Rossumc6913e71991-11-19 20:26:46 +0000796 if (z != NULL && z->ob_size != 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000797 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000798 }
799 else {
800 if (b->ob_size < 0)
801 z = x_add(a, b);
802 else
803 z = x_sub(a, b);
804 }
805 return (object *)z;
806}
807
808static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000809long_mul(a, b)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000810 longobject *a;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000811 longobject *b;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000812{
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000813 int size_a;
814 int size_b;
815 longobject *z;
816 int i;
817
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000818 size_a = ABS(a->ob_size);
819 size_b = ABS(b->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000820 z = alloclongobject(size_a + size_b);
821 if (z == NULL)
822 return NULL;
823 for (i = 0; i < z->ob_size; ++i)
824 z->ob_digit[i] = 0;
825 for (i = 0; i < size_a; ++i) {
826 twodigits carry = 0;
827 twodigits f = a->ob_digit[i];
828 int j;
829
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000830 SIGCHECK({
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000831 DECREF(z);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000832 return NULL;
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000833 })
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000834 for (j = 0; j < size_b; ++j) {
835 carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
836 z->ob_digit[i+j] = carry & MASK;
837 carry >>= SHIFT;
838 }
839 for (; carry != 0; ++j) {
840 assert(i+j < z->ob_size);
841 carry += z->ob_digit[i+j];
842 z->ob_digit[i+j] = carry & MASK;
843 carry >>= SHIFT;
844 }
845 }
846 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000847 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000848 if (b->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000849 z->ob_size = -(z->ob_size);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000850 return (object *) long_normalize(z);
851}
852
Guido van Rossume32e0141992-01-19 16:31:05 +0000853/* The / and % operators are now defined in terms of divmod().
854 The expression a mod b has the value a - b*floor(a/b).
855 The long_divrem function gives the remainder after division of
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000856 |a| by |b|, with the sign of a. This is also expressed
857 as a - b*trunc(a/b), if trunc truncates towards zero.
858 Some examples:
859 a b a rem b a mod b
860 13 10 3 3
861 -13 10 -3 7
862 13 -10 3 -7
863 -13 -10 -3 -3
864 So, to get from rem to mod, we have to add b if a and b
Guido van Rossum23d6f0e1991-05-14 12:06:49 +0000865 have different signs. We then subtract one from the 'div'
866 part of the outcome to keep the invariant intact. */
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000867
Guido van Rossume32e0141992-01-19 16:31:05 +0000868static int l_divmod PROTO((longobject *, longobject *,
869 longobject **, longobject **));
870static int
871l_divmod(v, w, pdiv, pmod)
872 longobject *v;
873 longobject *w;
874 longobject **pdiv;
875 longobject **pmod;
876{
877 longobject *div, *mod;
878
879 if (long_divrem(v, w, &div, &mod) < 0)
880 return -1;
881 if (mod->ob_size < 0 && w->ob_size > 0 ||
882 mod->ob_size > 0 && w->ob_size < 0) {
883 longobject *temp;
884 longobject *one;
885 temp = (longobject *) long_add(mod, w);
886 DECREF(mod);
887 mod = temp;
888 if (mod == NULL) {
889 DECREF(div);
890 return -1;
891 }
892 one = (longobject *) newlongobject(1L);
893 if (one == NULL ||
894 (temp = (longobject *) long_sub(div, one)) == NULL) {
895 DECREF(mod);
896 DECREF(div);
Guido van Rossume5372401993-03-16 12:15:04 +0000897 XDECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000898 return -1;
899 }
Guido van Rossume5372401993-03-16 12:15:04 +0000900 DECREF(one);
Guido van Rossume32e0141992-01-19 16:31:05 +0000901 DECREF(div);
902 div = temp;
903 }
904 *pdiv = div;
905 *pmod = mod;
906 return 0;
907}
908
909static object *
910long_div(v, w)
911 longobject *v;
912 longobject *w;
913{
914 longobject *div, *mod;
915 if (l_divmod(v, w, &div, &mod) < 0)
916 return NULL;
917 DECREF(mod);
918 return (object *)div;
919}
920
921static object *
922long_mod(v, w)
923 longobject *v;
924 longobject *w;
925{
926 longobject *div, *mod;
927 if (l_divmod(v, w, &div, &mod) < 0)
928 return NULL;
929 DECREF(div);
930 return (object *)mod;
931}
932
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000933static object *
934long_divmod(v, w)
935 longobject *v;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000936 longobject *w;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000937{
938 object *z;
Guido van Rossume32e0141992-01-19 16:31:05 +0000939 longobject *div, *mod;
940 if (l_divmod(v, w, &div, &mod) < 0)
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000941 return NULL;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000942 z = newtupleobject(2);
943 if (z != NULL) {
944 settupleitem(z, 0, (object *) div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000945 settupleitem(z, 1, (object *) mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000946 }
947 else {
948 DECREF(div);
Guido van Rossume32e0141992-01-19 16:31:05 +0000949 DECREF(mod);
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000950 }
951 return z;
952}
953
954static object *
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000955long_pow(a, b, c)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000956 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000957 longobject *b;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000958 longobject *c;
Guido van Rossumedcc38a1991-05-05 20:09:44 +0000959{
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000960 longobject *z, *div, *mod;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000961 int size_b, i;
962
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000963 size_b = b->ob_size;
Guido van Rossum4c260ff1992-01-14 18:36:43 +0000964 if (size_b < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000965 err_setstr(ValueError, "long integer to the negative power");
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000966 return NULL;
967 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000968 z = (longobject *)newlongobject(1L);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000969 INCREF(a);
970 for (i = 0; i < size_b; ++i) {
971 digit bi = b->ob_digit[i];
972 int j;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000973
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000974 for (j = 0; j < SHIFT; ++j) {
975 longobject *temp;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000976
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000977 if (bi & 1) {
Guido van Rossume32e0141992-01-19 16:31:05 +0000978 temp = (longobject *)long_mul(z, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000979 DECREF(z);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000980 if ((object*)c!=None && temp!=NULL) {
981 l_divmod(temp, c, &div, &mod);
982 XDECREF(div);
983 DECREF(temp);
984 temp = mod;
985 }
986 z = temp;
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000987 if (z == NULL)
988 break;
989 }
990 bi >>= 1;
991 if (bi == 0 && i+1 == size_b)
992 break;
Guido van Rossume32e0141992-01-19 16:31:05 +0000993 temp = (longobject *)long_mul(a, a);
Guido van Rossumc7ec9c91991-05-28 21:58:16 +0000994 DECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +0000995 if ((object*)c!=None && temp!=NULL) {
996 l_divmod(temp, c, &div, &mod);
997 XDECREF(div);
998 DECREF(temp);
999 temp = mod;
1000 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001001 a = temp;
1002 if (a == NULL) {
1003 DECREF(z);
1004 z = NULL;
1005 break;
1006 }
1007 }
Guido van Rossumc206c761995-01-10 15:23:19 +00001008 if (a == NULL || z == NULL)
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001009 break;
1010 }
1011 XDECREF(a);
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001012 if ((object*)c!=None && z!=NULL) {
1013 l_divmod(z, c, &div, &mod);
1014 XDECREF(div);
1015 DECREF(z);
1016 z=mod;
1017 }
Guido van Rossumc7ec9c91991-05-28 21:58:16 +00001018 return (object *)z;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001019}
1020
1021static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001022long_invert(v)
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001023 longobject *v;
1024{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001025 /* Implement ~x as -(x+1) */
1026 longobject *x;
Guido van Rossume32e0141992-01-19 16:31:05 +00001027 longobject *w;
1028 w = (longobject *)newlongobject(1L);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001029 if (w == NULL)
1030 return NULL;
1031 x = (longobject *) long_add(v, w);
1032 DECREF(w);
1033 if (x == NULL)
1034 return NULL;
1035 if (x->ob_size != 0)
1036 x->ob_size = -(x->ob_size);
1037 return (object *)x;
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001038}
1039
1040static object *
Guido van Rossumc6913e71991-11-19 20:26:46 +00001041long_pos(v)
1042 longobject *v;
1043{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001044 INCREF(v);
1045 return (object *)v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001046}
1047
1048static object *
1049long_neg(v)
1050 longobject *v;
1051{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001052 longobject *z;
1053 int i, n;
1054 n = ABS(v->ob_size);
1055 if (n == 0) {
1056 /* -0 == 0 */
Guido van Rossumc6913e71991-11-19 20:26:46 +00001057 INCREF(v);
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001058 return (object *) v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001059 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001060 z = alloclongobject(ABS(n));
1061 if (z == NULL)
1062 return NULL;
1063 for (i = 0; i < n; i++)
1064 z->ob_digit[i] = v->ob_digit[i];
1065 z->ob_size = -(v->ob_size);
1066 return (object *)z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001067}
1068
1069static object *
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001070long_abs(v)
1071 longobject *v;
1072{
1073 if (v->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001074 return long_neg(v);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001075 else {
1076 INCREF(v);
1077 return (object *)v;
1078 }
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001079}
1080
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001081static int
1082long_nonzero(v)
1083 longobject *v;
1084{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001085 return ABS(v->ob_size) != 0;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001086}
1087
1088static object *
1089long_rshift(a, b)
1090 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001091 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001092{
1093 longobject *z;
1094 long shiftby;
1095 int newsize, wordshift, loshift, hishift, i, j;
1096 digit lomask, himask;
1097
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001098 if (a->ob_size < 0) {
1099 /* Right shifting negative numbers is harder */
1100 longobject *a1, *a2, *a3;
1101 a1 = (longobject *) long_invert(a);
1102 if (a1 == NULL) return NULL;
1103 a2 = (longobject *) long_rshift(a1, b);
1104 DECREF(a1);
1105 if (a2 == NULL) return NULL;
1106 a3 = (longobject *) long_invert(a2);
1107 DECREF(a2);
1108 return (object *) a3;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001109 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001110
1111 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001112 if (shiftby == -1L && err_occurred())
1113 return NULL;
1114 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001115 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001116 return NULL;
1117 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001118 wordshift = shiftby / SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001119 newsize = ABS(a->ob_size) - wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001120 if (newsize <= 0) {
1121 z = alloclongobject(0);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001122 return (object *)z;
1123 }
1124 loshift = shiftby % SHIFT;
1125 hishift = SHIFT - loshift;
1126 lomask = ((digit)1 << hishift) - 1;
1127 himask = MASK ^ lomask;
1128 z = alloclongobject(newsize);
1129 if (z == NULL)
1130 return NULL;
1131 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001132 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001133 for (i = 0, j = wordshift; i < newsize; i++, j++) {
1134 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
1135 if (i+1 < newsize)
1136 z->ob_digit[i] |=
1137 (a->ob_digit[j+1] << hishift) & himask;
1138 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001139 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001140}
1141
1142static object *
1143long_lshift(a, b)
1144 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001145 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001146{
1147 longobject *z;
1148 long shiftby;
1149 int newsize, wordshift, loshift, hishift, i, j;
1150 digit lomask, himask;
1151
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001152 shiftby = getlongvalue((object *)b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001153 if (shiftby == -1L && err_occurred())
1154 return NULL;
1155 if (shiftby < 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +00001156 err_setstr(ValueError, "negative shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001157 return NULL;
1158 }
1159 if (shiftby > MASK) {
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001160 err_setstr(ValueError, "outrageous left shift count");
Guido van Rossumc6913e71991-11-19 20:26:46 +00001161 return NULL;
1162 }
1163 if (shiftby % SHIFT == 0) {
1164 wordshift = shiftby / SHIFT;
1165 loshift = 0;
1166 hishift = SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001167 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001168 lomask = MASK;
1169 himask = 0;
1170 }
1171 else {
1172 wordshift = shiftby / SHIFT + 1;
1173 loshift = SHIFT - shiftby%SHIFT;
1174 hishift = shiftby % SHIFT;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001175 newsize = ABS(a->ob_size) + wordshift;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001176 lomask = ((digit)1 << hishift) - 1;
1177 himask = MASK ^ lomask;
1178 }
1179 z = alloclongobject(newsize);
1180 if (z == NULL)
1181 return NULL;
1182 if (a->ob_size < 0)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001183 z->ob_size = -(z->ob_size);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001184 for (i = 0; i < wordshift; i++)
1185 z->ob_digit[i] = 0;
1186 for (i = wordshift, j = 0; i < newsize; i++, j++) {
1187 if (i > 0)
1188 z->ob_digit[i-1] |=
1189 (a->ob_digit[j] << hishift) & himask;
1190 z->ob_digit[i] =
1191 (a->ob_digit[j] >> loshift) & lomask;
1192 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001193 return (object *) long_normalize(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001194}
1195
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001196
1197/* Bitwise and/xor/or operations */
1198
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001199#define MAX(x, y) ((x) < (y) ? (y) : (x))
1200#define MIN(x, y) ((x) > (y) ? (y) : (x))
1201
Guido van Rossume32e0141992-01-19 16:31:05 +00001202static object *long_bitwise PROTO((longobject *, int, longobject *));
1203static object *
1204long_bitwise(a, op, b)
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001205 longobject *a;
1206 int op; /* '&', '|', '^' */
1207 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001208{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001209 digit maska, maskb; /* 0 or MASK */
1210 int negz;
1211 int size_a, size_b, size_z;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001212 longobject *z;
1213 int i;
Guido van Rossum8b27d921992-03-27 17:27:05 +00001214 digit diga, digb;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001215 object *v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001216
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001217 if (a->ob_size < 0) {
1218 a = (longobject *) long_invert(a);
1219 maska = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001220 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001221 else {
1222 INCREF(a);
1223 maska = 0;
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001224 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001225 if (b->ob_size < 0) {
1226 b = (longobject *) long_invert(b);
1227 maskb = MASK;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001228 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001229 else {
1230 INCREF(b);
1231 maskb = 0;
1232 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001233
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001234 size_a = a->ob_size;
1235 size_b = b->ob_size;
1236 size_z = MAX(size_a, size_b);
1237 z = alloclongobject(size_z);
1238 if (a == NULL || b == NULL || z == NULL) {
1239 XDECREF(a);
1240 XDECREF(b);
1241 XDECREF(z);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001242 return NULL;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001243 }
Guido van Rossumc6913e71991-11-19 20:26:46 +00001244
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001245 negz = 0;
1246 switch (op) {
1247 case '^':
1248 if (maska != maskb) {
1249 maska ^= MASK;
1250 negz = -1;
1251 }
1252 break;
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001253 case '&':
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001254 if (maska && maskb) {
1255 op = '|';
1256 maska ^= MASK;
1257 maskb ^= MASK;
1258 negz = -1;
1259 }
1260 break;
1261 case '|':
1262 if (maska || maskb) {
1263 op = '&';
1264 maska ^= MASK;
1265 maskb ^= MASK;
1266 negz = -1;
1267 }
1268 break;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001269 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001270
1271 for (i = 0; i < size_z; ++i) {
1272 diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
1273 digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
1274 switch (op) {
1275 case '&': z->ob_digit[i] = diga & digb; break;
1276 case '|': z->ob_digit[i] = diga | digb; break;
1277 case '^': z->ob_digit[i] = diga ^ digb; break;
1278 }
Guido van Rossumafbb8db1991-12-31 13:14:13 +00001279 }
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001280
1281 DECREF(a);
1282 DECREF(b);
1283 z = long_normalize(z);
1284 if (negz == 0)
1285 return (object *) z;
1286 v = long_invert(z);
1287 DECREF(z);
1288 return v;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001289}
1290
Guido van Rossumc6913e71991-11-19 20:26:46 +00001291static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001292long_and(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001293 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001294 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001295{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001296 return long_bitwise(a, '&', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001297}
1298
1299static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001300long_xor(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001301 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001302 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001303{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001304 return long_bitwise(a, '^', b);
Guido van Rossumc6913e71991-11-19 20:26:46 +00001305}
1306
1307static object *
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001308long_or(a, b)
Guido van Rossumc6913e71991-11-19 20:26:46 +00001309 longobject *a;
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001310 longobject *b;
Guido van Rossumc6913e71991-11-19 20:26:46 +00001311{
Guido van Rossum4c260ff1992-01-14 18:36:43 +00001312 return long_bitwise(a, '|', b);
Guido van Rossum23d6f0e1991-05-14 12:06:49 +00001313}
1314
Guido van Rossum234f9421993-06-17 12:35:49 +00001315static int
Guido van Rossume6eefc21992-08-14 12:06:52 +00001316long_coerce(pv, pw)
1317 object **pv;
1318 object **pw;
1319{
1320 if (is_intobject(*pw)) {
1321 *pw = newlongobject(getintvalue(*pw));
1322 INCREF(*pv);
1323 return 0;
1324 }
1325 return 1; /* Can't do it */
1326}
1327
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001328static object *
1329long_int(v)
1330 object *v;
1331{
1332 long x;
1333 x = getlongvalue(v);
1334 if (err_occurred())
1335 return NULL;
1336 return newintobject(x);
1337}
1338
1339static object *
1340long_long(v)
1341 object *v;
1342{
1343 INCREF(v);
1344 return v;
1345}
1346
1347static object *
1348long_float(v)
1349 object *v;
1350{
1351 return newfloatobject(dgetlongvalue(v));
1352}
1353
1354static object *
1355long_oct(v)
1356 object *v;
1357{
1358 return long_format(v, 8);
1359}
1360
1361static object *
1362long_hex(v)
1363 object *v;
1364{
1365 return long_format(v, 16);
1366}
1367
1368
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001369#define UF (unaryfunc)
1370#define BF (binaryfunc)
1371#define TF (ternaryfunc)
1372#define IF (inquiry)
Guido van Rossum8b27d921992-03-27 17:27:05 +00001373
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001374static number_methods long_as_number = {
Guido van Rossum8b27d921992-03-27 17:27:05 +00001375 BF long_add, /*nb_add*/
1376 BF long_sub, /*nb_subtract*/
1377 BF long_mul, /*nb_multiply*/
1378 BF long_div, /*nb_divide*/
1379 BF long_mod, /*nb_remainder*/
1380 BF long_divmod, /*nb_divmod*/
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001381 TF long_pow, /*nb_power*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001382 UF long_neg, /*nb_negative*/
1383 UF long_pos, /*tp_positive*/
1384 UF long_abs, /*tp_absolute*/
1385 IF long_nonzero,/*tp_nonzero*/
1386 UF long_invert, /*nb_invert*/
1387 BF long_lshift, /*nb_lshift*/
1388 BF long_rshift, /*nb_rshift*/
1389 BF long_and, /*nb_and*/
1390 BF long_xor, /*nb_xor*/
1391 BF long_or, /*nb_or*/
Guido van Rossume6eefc21992-08-14 12:06:52 +00001392 (int (*) FPROTO((object **, object **)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001393 (coercion)long_coerce, /*nb_coerce*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +00001394 UF long_int, /*nb_int*/
1395 UF long_long, /*nb_long*/
1396 UF long_float, /*nb_float*/
1397 UF long_oct, /*nb_oct*/
1398 UF long_hex, /*nb_hex*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001399};
1400
1401typeobject Longtype = {
1402 OB_HEAD_INIT(&Typetype)
1403 0,
1404 "long int",
1405 sizeof(longobject) - sizeof(digit),
1406 sizeof(digit),
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001407 (destructor)long_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +00001408 0, /*tp_print*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001409 0, /*tp_getattr*/
1410 0, /*tp_setattr*/
Guido van Rossum8b27d921992-03-27 17:27:05 +00001411 (int (*) FPROTO((object *, object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001412 (cmpfunc)long_compare, /*tp_compare*/
1413 (reprfunc)long_repr, /*tp_repr*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001414 &long_as_number,/*tp_as_number*/
1415 0, /*tp_as_sequence*/
1416 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +00001417 (long (*) FPROTO((object *)))
Guido van Rossumeb1fafc1994-08-29 12:47:19 +00001418 (hashfunc)long_hash, /*tp_hash*/
Guido van Rossumedcc38a1991-05-05 20:09:44 +00001419};