blob: e10dab2b3ea1fc4f8d1336c69d9e364cd2791714 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumbab9d031992-04-05 14:26:55 +00002Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Guido van Rossumf70e43a1991-02-19 12:39:46 +00003Netherlands.
4
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
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Integer object implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
29/* Standard Booleans */
Guido van Rossum3f5da241990-12-20 15:06:42 +000030
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000031intobject FalseObject = {
32 OB_HEAD_INIT(&Inttype)
33 0
34};
Guido van Rossum3f5da241990-12-20 15:06:42 +000035
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036intobject TrueObject = {
37 OB_HEAD_INIT(&Inttype)
38 1
39};
40
Guido van Rossum165e67e1990-10-14 20:02:26 +000041static object *
Guido van Rossum3a628451991-12-10 13:57:36 +000042err_ovf(msg)
43 char *msg;
Guido van Rossum165e67e1990-10-14 20:02:26 +000044{
Guido van Rossum3a628451991-12-10 13:57:36 +000045 err_setstr(OverflowError, msg);
Guido van Rossum165e67e1990-10-14 20:02:26 +000046 return NULL;
47}
48
Guido van Rossum3f5da241990-12-20 15:06:42 +000049/* Integers are quite normal objects, to make object handling uniform.
50 (Using odd pointers to represent integers would save much space
51 but require extra checks for this special case throughout the code.)
52 Since, a typical Python program spends much of its time allocating
53 and deallocating integers, these operations should be very fast.
54 Therefore we use a dedicated allocation scheme with a much lower
55 overhead (in space and time) than straight malloc(): a simple
56 dedicated free list, filled when necessary with memory from malloc().
57*/
58
59#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
60#define N_INTOBJECTS (BLOCK_SIZE / sizeof(intobject))
61
62static intobject *
63fill_free_list()
64{
65 intobject *p, *q;
66 p = NEW(intobject, N_INTOBJECTS);
67 if (p == NULL)
68 return (intobject *)err_nomem();
69 q = p + N_INTOBJECTS;
70 while (--q > p)
71 *(intobject **)q = q-1;
72 *(intobject **)q = NULL;
73 return p + N_INTOBJECTS - 1;
74}
75
76static intobject *free_list = NULL;
77
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078object *
79newintobject(ival)
80 long ival;
81{
Guido van Rossum3f5da241990-12-20 15:06:42 +000082 register intobject *v;
83 if (free_list == NULL) {
84 if ((free_list = fill_free_list()) == NULL)
85 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086 }
Guido van Rossum3f5da241990-12-20 15:06:42 +000087 v = free_list;
88 free_list = *(intobject **)free_list;
89 NEWREF(v);
90 v->ob_type = &Inttype;
91 v->ob_ival = ival;
92 return (object *) v;
93}
94
95static void
96int_dealloc(v)
97 intobject *v;
98{
99 *(intobject **)v = free_list;
100 free_list = v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101}
102
103long
104getintvalue(op)
105 register object *op;
106{
107 if (!is_intobject(op)) {
Guido van Rossum5c52b6a1990-10-21 22:11:03 +0000108 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109 return -1;
110 }
111 else
112 return ((intobject *)op) -> ob_ival;
113}
114
115/* Methods */
116
Guido van Rossum719f5fa1992-03-27 17:31:02 +0000117/* ARGSUSED */
Guido van Rossum90933611991-06-07 16:10:43 +0000118static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000119int_print(v, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120 intobject *v;
121 FILE *fp;
Guido van Rossum719f5fa1992-03-27 17:31:02 +0000122 int flags; /* Not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123{
124 fprintf(fp, "%ld", v->ob_ival);
Guido van Rossum90933611991-06-07 16:10:43 +0000125 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000126}
127
128static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000129int_repr(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 intobject *v;
131{
132 char buf[20];
133 sprintf(buf, "%ld", v->ob_ival);
134 return newstringobject(buf);
135}
136
137static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000138int_compare(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139 intobject *v, *w;
140{
141 register long i = v->ob_ival;
142 register long j = w->ob_ival;
143 return (i < j) ? -1 : (i > j) ? 1 : 0;
144}
145
146static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000147int_add(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000149 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150{
151 register long a, b, x;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000153 b = w->ob_ival;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154 x = a + b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000155 if ((x^a) < 0 && (x^b) < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000156 return err_ovf("integer addition");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000157 return newintobject(x);
158}
159
160static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000161int_sub(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000163 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164{
165 register long a, b, x;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000167 b = w->ob_ival;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 x = a - b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000169 if ((x^a) < 0 && (x^~b) < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000170 return err_ovf("integer subtraction");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171 return newintobject(x);
172}
173
174static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000175int_mul(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000177 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178{
179 register long a, b;
180 double x;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000182 b = w->ob_ival;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183 x = (double)a * (double)b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000184 if (x > 0x7fffffff || x < (double) (long) 0x80000000)
Guido van Rossum3a628451991-12-10 13:57:36 +0000185 return err_ovf("integer multiplication");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186 return newintobject(a * b);
187}
188
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000189static int
190i_divmod(x, y, p_xdivy, p_xmody)
191 register intobject *x, *y;
192 long *p_xdivy, *p_xmody;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193{
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000194 long xi = x->ob_ival;
195 long yi = y->ob_ival;
196 long xdivy, xmody;
197
198 if (yi == 0) {
199 err_setstr(ZeroDivisionError, "integer division or modulo");
200 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201 }
Guido van Rossum00466951991-05-05 20:08:27 +0000202 if (yi < 0) {
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000203 if (xi < 0)
204 xdivy = -xi / -yi;
205 else
206 xdivy = - (xi / -yi);
Guido van Rossum00466951991-05-05 20:08:27 +0000207 }
208 else {
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000209 if (xi < 0)
210 xdivy = - (-xi / yi);
211 else
212 xdivy = xi / yi;
Guido van Rossum00466951991-05-05 20:08:27 +0000213 }
214 xmody = xi - xdivy*yi;
215 if (xmody < 0 && yi > 0 || xmody > 0 && yi < 0) {
216 xmody += yi;
217 xdivy -= 1;
218 }
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000219 *p_xdivy = xdivy;
220 *p_xmody = xmody;
221 return 0;
222}
223
224static object *
225int_div(x, y)
226 intobject *x;
227 intobject *y;
228{
229 long d, m;
230 if (i_divmod(x, y, &d, &m) < 0)
231 return NULL;
232 return newintobject(d);
233}
234
235static object *
236int_mod(x, y)
237 intobject *x;
238 intobject *y;
239{
240 long d, m;
241 if (i_divmod(x, y, &d, &m) < 0)
242 return NULL;
Guido van Rossum719f5fa1992-03-27 17:31:02 +0000243 return newintobject(m);
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000244}
245
246static object *
247int_divmod(x, y)
248 intobject *x;
249 intobject *y;
250{
251 object *v, *v0, *v1;
252 long d, m;
253 if (i_divmod(x, y, &d, &m) < 0)
254 return NULL;
Guido van Rossum00466951991-05-05 20:08:27 +0000255 v = newtupleobject(2);
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000256 v0 = newintobject(d);
257 v1 = newintobject(m);
Guido van Rossum00466951991-05-05 20:08:27 +0000258 if (v == NULL || v0 == NULL || v1 == NULL ||
259 settupleitem(v, 0, v0) != 0 ||
260 settupleitem(v, 1, v1) != 0) {
261 XDECREF(v);
262 XDECREF(v0);
263 XDECREF(v1);
264 v = NULL;
265 }
266 return v;
267}
268
269static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000270int_pow(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000271 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000272 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000273{
274 register long iv, iw, ix;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000275 iv = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000276 iw = w->ob_ival;
Guido van Rossum00466951991-05-05 20:08:27 +0000277 if (iw < 0) {
Guido van Rossum3a628451991-12-10 13:57:36 +0000278 err_setstr(ValueError, "integer to the negative power");
Guido van Rossum00466951991-05-05 20:08:27 +0000279 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280 }
Guido van Rossum00466951991-05-05 20:08:27 +0000281 ix = 1;
282 while (--iw >= 0) {
283 long prev = ix;
284 ix = ix * iv;
285 if (iv == 0)
286 break; /* 0 to some power -- avoid ix / 0 */
287 if (ix / iv != prev)
Guido van Rossum3a628451991-12-10 13:57:36 +0000288 return err_ovf("integer pow()");
Guido van Rossum00466951991-05-05 20:08:27 +0000289 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290 return newintobject(ix);
291}
292
293static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000294int_neg(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 intobject *v;
296{
297 register long a, x;
298 a = v->ob_ival;
299 x = -a;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000300 if (a < 0 && x < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000301 return err_ovf("integer negation");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302 return newintobject(x);
303}
304
305static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000306int_pos(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307 intobject *v;
308{
309 INCREF(v);
310 return (object *)v;
311}
312
Guido van Rossum00466951991-05-05 20:08:27 +0000313static object *
314int_abs(v)
315 intobject *v;
316{
317 if (v->ob_ival >= 0)
318 return int_pos(v);
319 else
320 return int_neg(v);
321}
322
Guido van Rossum0bff0151991-05-14 12:05:32 +0000323static int
324int_nonzero(v)
325 intobject *v;
326{
327 return v->ob_ival != 0;
328}
329
Guido van Rossum7928cd71991-10-24 14:59:31 +0000330static object *
331int_invert(v)
332 intobject *v;
333{
334 return newintobject(~v->ob_ival);
335}
336
337static object *
338int_lshift(v, w)
339 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000340 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000341{
342 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000343 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000344 b = w->ob_ival;
Guido van Rossumf3b351f1992-01-14 18:33:22 +0000345 if (b < 0) {
346 err_setstr(ValueError, "negative shift count");
347 return NULL;
348 }
349 if (a == 0 || b == 0) {
350 INCREF(v);
351 return (object *) v;
352 }
353 if (b >= 32) {
354 return newintobject(0L);
355 }
356 a = (unsigned long)a << b;
357 return newintobject(a);
Guido van Rossum7928cd71991-10-24 14:59:31 +0000358}
359
360static object *
361int_rshift(v, w)
362 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000363 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000364{
365 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000366 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000367 b = w->ob_ival;
Guido van Rossumf3b351f1992-01-14 18:33:22 +0000368 if (b < 0) {
369 err_setstr(ValueError, "negative shift count");
370 return NULL;
371 }
372 if (a == 0 || b == 0) {
373 INCREF(v);
374 return (object *) v;
375 }
376 if (b >= 32) {
377 if (a < 0)
378 a = -1;
379 else
380 a = 0;
381 }
382 else {
383 if (a < 0)
384 a = ~( ~(unsigned long)a >> b );
385 else
386 a = (unsigned long)a >> b;
387 }
388 return newintobject(a);
Guido van Rossum7928cd71991-10-24 14:59:31 +0000389}
390
391static object *
392int_and(v, w)
393 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000394 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000395{
396 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000397 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000398 b = w->ob_ival;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000399 return newintobject(a & b);
400}
401
402static object *
403int_xor(v, w)
404 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000405 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000406{
407 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000408 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000409 b = w->ob_ival;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000410 return newintobject(a ^ b);
411}
412
413static object *
414int_or(v, w)
415 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000416 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000417{
418 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000419 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000420 b = w->ob_ival;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000421 return newintobject(a | b);
422}
423
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000424static object *
425int_int(v)
426 object *v;
427{
428 INCREF(v);
429 return v;
430}
431
432static object *
433int_long(v)
434 object *v;
435{
436 long x = getintvalue(v);
437 return newlongobject(x);
438}
439
440static object *
441int_float(v)
442 object *v;
443{
444 long x = getintvalue(v);
445 return newfloatobject((double)x);
446}
447
448static object *
449int_oct(v)
450 object *v;
451{
452 char buf[20];
453 long x = getintvalue(v);
454 if (x == 0)
455 strcpy(buf, "0");
456 else if (x > 0)
457 sprintf(buf, "0%lo", x);
458 else
459 sprintf(buf, "-0%lo", -x);
460 return newstringobject(buf);
461}
462
463static object *
464int_hex(v)
465 object *v;
466{
467 char buf[20];
468 long x = getintvalue(v);
469 if (x >= 0)
470 sprintf(buf, "0x%lx", x);
471 else
472 sprintf(buf, "-0x%lx", -x);
473 return newstringobject(buf);
474}
475
476
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000477static number_methods int_as_number = {
Guido van Rossum00466951991-05-05 20:08:27 +0000478 int_add, /*nb_add*/
479 int_sub, /*nb_subtract*/
480 int_mul, /*nb_multiply*/
481 int_div, /*nb_divide*/
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000482 int_mod, /*nb_remainder*/
Guido van Rossum00466951991-05-05 20:08:27 +0000483 int_divmod, /*nb_divmod*/
484 int_pow, /*nb_power*/
485 int_neg, /*nb_negative*/
486 int_pos, /*nb_positive*/
487 int_abs, /*nb_absolute*/
Guido van Rossum0bff0151991-05-14 12:05:32 +0000488 int_nonzero, /*nb_nonzero*/
Guido van Rossum7928cd71991-10-24 14:59:31 +0000489 int_invert, /*nb_invert*/
490 int_lshift, /*nb_lshift*/
491 int_rshift, /*nb_rshift*/
492 int_and, /*nb_and*/
493 int_xor, /*nb_xor*/
494 int_or, /*nb_or*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000495 0, /*nb_coerce*/
496 int_int, /*nb_int*/
497 int_long, /*nb_long*/
498 int_float, /*nb_float*/
499 int_oct, /*nb_oct*/
500 int_hex, /*nb_hex*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501};
502
503typeobject Inttype = {
504 OB_HEAD_INIT(&Typetype)
505 0,
506 "int",
507 sizeof(intobject),
508 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000509 int_dealloc, /*tp_dealloc*/
510 int_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511 0, /*tp_getattr*/
512 0, /*tp_setattr*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000513 int_compare, /*tp_compare*/
514 int_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000515 &int_as_number, /*tp_as_number*/
516 0, /*tp_as_sequence*/
517 0, /*tp_as_mapping*/
518};