blob: 858458c0848da1e1e2aebe7323794b69f8fed21d [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossume5372401993-03-16 12:15:04 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +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
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 Rossume5372401993-03-16 12:15:04 +000028#include "modsupport.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000029
30/* Standard Booleans */
Guido van Rossum3f5da241990-12-20 15:06:42 +000031
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032intobject FalseObject = {
33 OB_HEAD_INIT(&Inttype)
34 0
35};
Guido van Rossum3f5da241990-12-20 15:06:42 +000036
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000037intobject TrueObject = {
38 OB_HEAD_INIT(&Inttype)
39 1
40};
41
Guido van Rossum165e67e1990-10-14 20:02:26 +000042static object *
Guido van Rossum3a628451991-12-10 13:57:36 +000043err_ovf(msg)
44 char *msg;
Guido van Rossum165e67e1990-10-14 20:02:26 +000045{
Guido van Rossum3a628451991-12-10 13:57:36 +000046 err_setstr(OverflowError, msg);
Guido van Rossum165e67e1990-10-14 20:02:26 +000047 return NULL;
48}
49
Guido van Rossum3f5da241990-12-20 15:06:42 +000050/* Integers are quite normal objects, to make object handling uniform.
51 (Using odd pointers to represent integers would save much space
52 but require extra checks for this special case throughout the code.)
53 Since, a typical Python program spends much of its time allocating
54 and deallocating integers, these operations should be very fast.
55 Therefore we use a dedicated allocation scheme with a much lower
56 overhead (in space and time) than straight malloc(): a simple
57 dedicated free list, filled when necessary with memory from malloc().
58*/
59
60#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
61#define N_INTOBJECTS (BLOCK_SIZE / sizeof(intobject))
62
63static intobject *
64fill_free_list()
65{
66 intobject *p, *q;
67 p = NEW(intobject, N_INTOBJECTS);
68 if (p == NULL)
69 return (intobject *)err_nomem();
70 q = p + N_INTOBJECTS;
71 while (--q > p)
72 *(intobject **)q = q-1;
73 *(intobject **)q = NULL;
74 return p + N_INTOBJECTS - 1;
75}
76
77static intobject *free_list = NULL;
78
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079object *
80newintobject(ival)
81 long ival;
82{
Guido van Rossum3f5da241990-12-20 15:06:42 +000083 register intobject *v;
84 if (free_list == NULL) {
85 if ((free_list = fill_free_list()) == NULL)
86 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087 }
Guido van Rossum3f5da241990-12-20 15:06:42 +000088 v = free_list;
89 free_list = *(intobject **)free_list;
90 NEWREF(v);
91 v->ob_type = &Inttype;
92 v->ob_ival = ival;
93 return (object *) v;
94}
95
96static void
97int_dealloc(v)
98 intobject *v;
99{
100 *(intobject **)v = free_list;
101 free_list = v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102}
103
104long
105getintvalue(op)
106 register object *op;
107{
108 if (!is_intobject(op)) {
Guido van Rossum5c52b6a1990-10-21 22:11:03 +0000109 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 return -1;
111 }
112 else
113 return ((intobject *)op) -> ob_ival;
114}
115
116/* Methods */
117
Guido van Rossum719f5fa1992-03-27 17:31:02 +0000118/* ARGSUSED */
Guido van Rossum90933611991-06-07 16:10:43 +0000119static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000120int_print(v, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121 intobject *v;
122 FILE *fp;
Guido van Rossum719f5fa1992-03-27 17:31:02 +0000123 int flags; /* Not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124{
125 fprintf(fp, "%ld", v->ob_ival);
Guido van Rossum90933611991-06-07 16:10:43 +0000126 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127}
128
129static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000130int_repr(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131 intobject *v;
132{
133 char buf[20];
134 sprintf(buf, "%ld", v->ob_ival);
135 return newstringobject(buf);
136}
137
138static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000139int_compare(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000140 intobject *v, *w;
141{
142 register long i = v->ob_ival;
143 register long j = w->ob_ival;
144 return (i < j) ? -1 : (i > j) ? 1 : 0;
145}
146
147static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000148int_add(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000150 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151{
152 register long a, b, x;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000154 b = w->ob_ival;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 x = a + b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000156 if ((x^a) < 0 && (x^b) < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000157 return err_ovf("integer addition");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000158 return newintobject(x);
159}
160
161static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000162int_sub(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000164 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165{
166 register long a, b, x;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000167 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000168 b = w->ob_ival;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000169 x = a - b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000170 if ((x^a) < 0 && (x^~b) < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000171 return err_ovf("integer subtraction");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 return newintobject(x);
173}
174
175static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000176int_mul(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000178 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000179{
180 register long a, b;
181 double x;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000183 b = w->ob_ival;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184 x = (double)a * (double)b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000185 if (x > 0x7fffffff || x < (double) (long) 0x80000000)
Guido van Rossum3a628451991-12-10 13:57:36 +0000186 return err_ovf("integer multiplication");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187 return newintobject(a * b);
188}
189
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000190static int
191i_divmod(x, y, p_xdivy, p_xmody)
192 register intobject *x, *y;
193 long *p_xdivy, *p_xmody;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194{
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000195 long xi = x->ob_ival;
196 long yi = y->ob_ival;
197 long xdivy, xmody;
198
199 if (yi == 0) {
200 err_setstr(ZeroDivisionError, "integer division or modulo");
201 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 }
Guido van Rossum00466951991-05-05 20:08:27 +0000203 if (yi < 0) {
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000204 if (xi < 0)
205 xdivy = -xi / -yi;
206 else
207 xdivy = - (xi / -yi);
Guido van Rossum00466951991-05-05 20:08:27 +0000208 }
209 else {
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000210 if (xi < 0)
211 xdivy = - (-xi / yi);
212 else
213 xdivy = xi / yi;
Guido van Rossum00466951991-05-05 20:08:27 +0000214 }
215 xmody = xi - xdivy*yi;
216 if (xmody < 0 && yi > 0 || xmody > 0 && yi < 0) {
217 xmody += yi;
218 xdivy -= 1;
219 }
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000220 *p_xdivy = xdivy;
221 *p_xmody = xmody;
222 return 0;
223}
224
225static object *
226int_div(x, y)
227 intobject *x;
228 intobject *y;
229{
230 long d, m;
231 if (i_divmod(x, y, &d, &m) < 0)
232 return NULL;
233 return newintobject(d);
234}
235
236static object *
237int_mod(x, y)
238 intobject *x;
239 intobject *y;
240{
241 long d, m;
242 if (i_divmod(x, y, &d, &m) < 0)
243 return NULL;
Guido van Rossum719f5fa1992-03-27 17:31:02 +0000244 return newintobject(m);
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000245}
246
247static object *
248int_divmod(x, y)
249 intobject *x;
250 intobject *y;
251{
252 object *v, *v0, *v1;
253 long d, m;
254 if (i_divmod(x, y, &d, &m) < 0)
255 return NULL;
Guido van Rossume5372401993-03-16 12:15:04 +0000256 return mkvalue("(ll)", d, m);
Guido van Rossum00466951991-05-05 20:08:27 +0000257}
258
259static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000260int_pow(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000262 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263{
264 register long iv, iw, ix;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000265 iv = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000266 iw = w->ob_ival;
Guido van Rossum00466951991-05-05 20:08:27 +0000267 if (iw < 0) {
Guido van Rossum3a628451991-12-10 13:57:36 +0000268 err_setstr(ValueError, "integer to the negative power");
Guido van Rossum00466951991-05-05 20:08:27 +0000269 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270 }
Guido van Rossum00466951991-05-05 20:08:27 +0000271 ix = 1;
272 while (--iw >= 0) {
273 long prev = ix;
274 ix = ix * iv;
275 if (iv == 0)
276 break; /* 0 to some power -- avoid ix / 0 */
277 if (ix / iv != prev)
Guido van Rossum3a628451991-12-10 13:57:36 +0000278 return err_ovf("integer pow()");
Guido van Rossum00466951991-05-05 20:08:27 +0000279 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280 return newintobject(ix);
281}
282
283static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000284int_neg(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285 intobject *v;
286{
287 register long a, x;
288 a = v->ob_ival;
289 x = -a;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000290 if (a < 0 && x < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000291 return err_ovf("integer negation");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 return newintobject(x);
293}
294
295static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000296int_pos(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 intobject *v;
298{
299 INCREF(v);
300 return (object *)v;
301}
302
Guido van Rossum00466951991-05-05 20:08:27 +0000303static object *
304int_abs(v)
305 intobject *v;
306{
307 if (v->ob_ival >= 0)
308 return int_pos(v);
309 else
310 return int_neg(v);
311}
312
Guido van Rossum0bff0151991-05-14 12:05:32 +0000313static int
314int_nonzero(v)
315 intobject *v;
316{
317 return v->ob_ival != 0;
318}
319
Guido van Rossum7928cd71991-10-24 14:59:31 +0000320static object *
321int_invert(v)
322 intobject *v;
323{
324 return newintobject(~v->ob_ival);
325}
326
327static object *
328int_lshift(v, w)
329 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000330 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000331{
332 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000333 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000334 b = w->ob_ival;
Guido van Rossumf3b351f1992-01-14 18:33:22 +0000335 if (b < 0) {
336 err_setstr(ValueError, "negative shift count");
337 return NULL;
338 }
339 if (a == 0 || b == 0) {
340 INCREF(v);
341 return (object *) v;
342 }
343 if (b >= 32) {
344 return newintobject(0L);
345 }
346 a = (unsigned long)a << b;
347 return newintobject(a);
Guido van Rossum7928cd71991-10-24 14:59:31 +0000348}
349
350static object *
351int_rshift(v, w)
352 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000353 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000354{
355 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000356 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000357 b = w->ob_ival;
Guido van Rossumf3b351f1992-01-14 18:33:22 +0000358 if (b < 0) {
359 err_setstr(ValueError, "negative shift count");
360 return NULL;
361 }
362 if (a == 0 || b == 0) {
363 INCREF(v);
364 return (object *) v;
365 }
366 if (b >= 32) {
367 if (a < 0)
368 a = -1;
369 else
370 a = 0;
371 }
372 else {
373 if (a < 0)
374 a = ~( ~(unsigned long)a >> b );
375 else
376 a = (unsigned long)a >> b;
377 }
378 return newintobject(a);
Guido van Rossum7928cd71991-10-24 14:59:31 +0000379}
380
381static object *
382int_and(v, w)
383 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000384 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000385{
386 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000387 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000388 b = w->ob_ival;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000389 return newintobject(a & b);
390}
391
392static object *
393int_xor(v, w)
394 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000395 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000396{
397 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000398 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000399 b = w->ob_ival;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000400 return newintobject(a ^ b);
401}
402
403static object *
404int_or(v, w)
405 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000406 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000407{
408 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000409 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000410 b = w->ob_ival;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000411 return newintobject(a | b);
412}
413
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000414static object *
415int_int(v)
416 object *v;
417{
418 INCREF(v);
419 return v;
420}
421
422static object *
423int_long(v)
424 object *v;
425{
426 long x = getintvalue(v);
427 return newlongobject(x);
428}
429
430static object *
431int_float(v)
432 object *v;
433{
434 long x = getintvalue(v);
435 return newfloatobject((double)x);
436}
437
438static object *
439int_oct(v)
440 object *v;
441{
442 char buf[20];
443 long x = getintvalue(v);
444 if (x == 0)
445 strcpy(buf, "0");
446 else if (x > 0)
447 sprintf(buf, "0%lo", x);
448 else
449 sprintf(buf, "-0%lo", -x);
450 return newstringobject(buf);
451}
452
453static object *
454int_hex(v)
455 object *v;
456{
457 char buf[20];
458 long x = getintvalue(v);
459 if (x >= 0)
460 sprintf(buf, "0x%lx", x);
461 else
462 sprintf(buf, "-0x%lx", -x);
463 return newstringobject(buf);
464}
465
466
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000467static number_methods int_as_number = {
Guido van Rossum00466951991-05-05 20:08:27 +0000468 int_add, /*nb_add*/
469 int_sub, /*nb_subtract*/
470 int_mul, /*nb_multiply*/
471 int_div, /*nb_divide*/
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000472 int_mod, /*nb_remainder*/
Guido van Rossum00466951991-05-05 20:08:27 +0000473 int_divmod, /*nb_divmod*/
474 int_pow, /*nb_power*/
475 int_neg, /*nb_negative*/
476 int_pos, /*nb_positive*/
477 int_abs, /*nb_absolute*/
Guido van Rossum0bff0151991-05-14 12:05:32 +0000478 int_nonzero, /*nb_nonzero*/
Guido van Rossum7928cd71991-10-24 14:59:31 +0000479 int_invert, /*nb_invert*/
480 int_lshift, /*nb_lshift*/
481 int_rshift, /*nb_rshift*/
482 int_and, /*nb_and*/
483 int_xor, /*nb_xor*/
484 int_or, /*nb_or*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000485 0, /*nb_coerce*/
486 int_int, /*nb_int*/
487 int_long, /*nb_long*/
488 int_float, /*nb_float*/
489 int_oct, /*nb_oct*/
490 int_hex, /*nb_hex*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000491};
492
493typeobject Inttype = {
494 OB_HEAD_INIT(&Typetype)
495 0,
496 "int",
497 sizeof(intobject),
498 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000499 int_dealloc, /*tp_dealloc*/
500 int_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501 0, /*tp_getattr*/
502 0, /*tp_setattr*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000503 int_compare, /*tp_compare*/
504 int_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000505 &int_as_number, /*tp_as_number*/
506 0, /*tp_as_sequence*/
507 0, /*tp_as_mapping*/
508};