blob: edffacefe48a42c91635d13a241587bd27b3180e [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
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
49static object *
Guido van Rossum3a628451991-12-10 13:57:36 +000050err_zdiv(msg)
51 char *msg;
Guido van Rossum165e67e1990-10-14 20:02:26 +000052{
Guido van Rossum3a628451991-12-10 13:57:36 +000053 err_setstr(ZeroDivisionError, msg);
Guido van Rossum165e67e1990-10-14 20:02:26 +000054 return NULL;
55}
56
Guido van Rossum3f5da241990-12-20 15:06:42 +000057/* Integers are quite normal objects, to make object handling uniform.
58 (Using odd pointers to represent integers would save much space
59 but require extra checks for this special case throughout the code.)
60 Since, a typical Python program spends much of its time allocating
61 and deallocating integers, these operations should be very fast.
62 Therefore we use a dedicated allocation scheme with a much lower
63 overhead (in space and time) than straight malloc(): a simple
64 dedicated free list, filled when necessary with memory from malloc().
65*/
66
67#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
68#define N_INTOBJECTS (BLOCK_SIZE / sizeof(intobject))
69
70static intobject *
71fill_free_list()
72{
73 intobject *p, *q;
74 p = NEW(intobject, N_INTOBJECTS);
75 if (p == NULL)
76 return (intobject *)err_nomem();
77 q = p + N_INTOBJECTS;
78 while (--q > p)
79 *(intobject **)q = q-1;
80 *(intobject **)q = NULL;
81 return p + N_INTOBJECTS - 1;
82}
83
84static intobject *free_list = NULL;
85
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086object *
87newintobject(ival)
88 long ival;
89{
Guido van Rossum3f5da241990-12-20 15:06:42 +000090 register intobject *v;
91 if (free_list == NULL) {
92 if ((free_list = fill_free_list()) == NULL)
93 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094 }
Guido van Rossum3f5da241990-12-20 15:06:42 +000095 v = free_list;
96 free_list = *(intobject **)free_list;
97 NEWREF(v);
98 v->ob_type = &Inttype;
99 v->ob_ival = ival;
100 return (object *) v;
101}
102
103static void
104int_dealloc(v)
105 intobject *v;
106{
107 *(intobject **)v = free_list;
108 free_list = v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109}
110
111long
112getintvalue(op)
113 register object *op;
114{
115 if (!is_intobject(op)) {
Guido van Rossum5c52b6a1990-10-21 22:11:03 +0000116 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117 return -1;
118 }
119 else
120 return ((intobject *)op) -> ob_ival;
121}
122
123/* Methods */
124
Guido van Rossum90933611991-06-07 16:10:43 +0000125static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000126int_print(v, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127 intobject *v;
128 FILE *fp;
129 int flags;
130{
131 fprintf(fp, "%ld", v->ob_ival);
Guido van Rossum90933611991-06-07 16:10:43 +0000132 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133}
134
135static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000136int_repr(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137 intobject *v;
138{
139 char buf[20];
140 sprintf(buf, "%ld", v->ob_ival);
141 return newstringobject(buf);
142}
143
144static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000145int_compare(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000146 intobject *v, *w;
147{
148 register long i = v->ob_ival;
149 register long j = w->ob_ival;
150 return (i < j) ? -1 : (i > j) ? 1 : 0;
151}
152
153static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000154int_add(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 intobject *v;
156 register object *w;
157{
158 register long a, b, x;
159 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000160 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000161 return NULL;
162 }
163 a = v->ob_ival;
164 b = ((intobject *)w) -> ob_ival;
165 x = a + b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000166 if ((x^a) < 0 && (x^b) < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000167 return err_ovf("integer addition");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 return newintobject(x);
169}
170
171static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000172int_sub(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173 intobject *v;
174 register object *w;
175{
176 register long a, b, x;
177 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000178 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000179 return NULL;
180 }
181 a = v->ob_ival;
182 b = ((intobject *)w) -> ob_ival;
183 x = a - b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000184 if ((x^a) < 0 && (x^~b) < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000185 return err_ovf("integer subtraction");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186 return newintobject(x);
187}
188
189static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000190int_mul(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 intobject *v;
192 register object *w;
193{
194 register long a, b;
195 double x;
196 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000197 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198 return NULL;
199 }
200 a = v->ob_ival;
201 b = ((intobject *)w) -> ob_ival;
202 x = (double)a * (double)b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000203 if (x > 0x7fffffff || x < (double) (long) 0x80000000)
Guido van Rossum3a628451991-12-10 13:57:36 +0000204 return err_ovf("integer multiplication");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205 return newintobject(a * b);
206}
207
208static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000209int_div(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210 intobject *v;
211 register object *w;
212{
Guido van Rossum7928cd71991-10-24 14:59:31 +0000213 register long a, b, x;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000215 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000216 return NULL;
217 }
Guido van Rossum165e67e1990-10-14 20:02:26 +0000218 if (((intobject *)w) -> ob_ival == 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000219 return err_zdiv("integer division");
Guido van Rossum7928cd71991-10-24 14:59:31 +0000220 a = v->ob_ival;
221 b = ((intobject *)w) -> ob_ival;
222 /* Make sure we always truncate towards zero */
223 /* XXX What if a == -0x80000000? */
224 if (a < 0) {
225 if (b < 0)
226 x = -a / -b;
227 else
228 x = -(-a / b);
229 }
230 else {
231 if (b < 0)
232 x = -(a / -b);
233 else
234 x = a / b;
235 }
236 return newintobject(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237}
238
239static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000240int_rem(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241 intobject *v;
242 register object *w;
243{
244 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000245 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000246 return NULL;
247 }
Guido van Rossum165e67e1990-10-14 20:02:26 +0000248 if (((intobject *)w) -> ob_ival == 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000249 return err_zdiv("integer remainder");
Guido van Rossum7928cd71991-10-24 14:59:31 +0000250 /* XXX Need to fix this similar to int_div */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 return newintobject(v->ob_ival % ((intobject *)w) -> ob_ival);
252}
253
254static object *
Guido van Rossum00466951991-05-05 20:08:27 +0000255int_divmod(x, y)
256 intobject *x;
257 register object *y;
258{
259 object *v, *v0, *v1;
260 long xi, yi, xdivy, xmody;
261 if (!is_intobject(y)) {
262 err_badarg();
263 return NULL;
264 }
265 xi = x->ob_ival;
266 yi = getintvalue(y);
267 if (yi == 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000268 return err_zdiv("integer divmod()");
Guido van Rossum00466951991-05-05 20:08:27 +0000269 if (yi < 0) {
270 xdivy = -xi / -yi;
271 }
272 else {
273 xdivy = xi / yi;
274 }
275 xmody = xi - xdivy*yi;
276 if (xmody < 0 && yi > 0 || xmody > 0 && yi < 0) {
277 xmody += yi;
278 xdivy -= 1;
279 }
280 v = newtupleobject(2);
281 v0 = newintobject(xdivy);
282 v1 = newintobject(xmody);
283 if (v == NULL || v0 == NULL || v1 == NULL ||
284 settupleitem(v, 0, v0) != 0 ||
285 settupleitem(v, 1, v1) != 0) {
286 XDECREF(v);
287 XDECREF(v0);
288 XDECREF(v1);
289 v = NULL;
290 }
291 return v;
292}
293
294static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000295int_pow(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296 intobject *v;
297 register object *w;
298{
299 register long iv, iw, ix;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000301 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302 return NULL;
303 }
304 iv = v->ob_ival;
305 iw = ((intobject *)w)->ob_ival;
Guido van Rossum00466951991-05-05 20:08:27 +0000306 if (iw < 0) {
Guido van Rossum3a628451991-12-10 13:57:36 +0000307 err_setstr(ValueError, "integer to the negative power");
Guido van Rossum00466951991-05-05 20:08:27 +0000308 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000309 }
Guido van Rossum00466951991-05-05 20:08:27 +0000310 ix = 1;
311 while (--iw >= 0) {
312 long prev = ix;
313 ix = ix * iv;
314 if (iv == 0)
315 break; /* 0 to some power -- avoid ix / 0 */
316 if (ix / iv != prev)
Guido van Rossum3a628451991-12-10 13:57:36 +0000317 return err_ovf("integer pow()");
Guido van Rossum00466951991-05-05 20:08:27 +0000318 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319 return newintobject(ix);
320}
321
322static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000323int_neg(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324 intobject *v;
325{
326 register long a, x;
327 a = v->ob_ival;
328 x = -a;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000329 if (a < 0 && x < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000330 return err_ovf("integer negation");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 return newintobject(x);
332}
333
334static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000335int_pos(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000336 intobject *v;
337{
338 INCREF(v);
339 return (object *)v;
340}
341
Guido van Rossum00466951991-05-05 20:08:27 +0000342static object *
343int_abs(v)
344 intobject *v;
345{
346 if (v->ob_ival >= 0)
347 return int_pos(v);
348 else
349 return int_neg(v);
350}
351
Guido van Rossum0bff0151991-05-14 12:05:32 +0000352static int
353int_nonzero(v)
354 intobject *v;
355{
356 return v->ob_ival != 0;
357}
358
Guido van Rossum7928cd71991-10-24 14:59:31 +0000359static object *
360int_invert(v)
361 intobject *v;
362{
363 return newintobject(~v->ob_ival);
364}
365
366static object *
367int_lshift(v, w)
368 intobject *v;
369 register object *w;
370{
371 register long a, b;
372 if (!is_intobject(w)) {
373 err_badarg();
374 return NULL;
375 }
376 a = v->ob_ival;
377 b = ((intobject *)w) -> ob_ival;
Guido van Rossumf3b351f1992-01-14 18:33:22 +0000378 if (b < 0) {
379 err_setstr(ValueError, "negative shift count");
380 return NULL;
381 }
382 if (a == 0 || b == 0) {
383 INCREF(v);
384 return (object *) v;
385 }
386 if (b >= 32) {
387 return newintobject(0L);
388 }
389 a = (unsigned long)a << b;
390 return newintobject(a);
Guido van Rossum7928cd71991-10-24 14:59:31 +0000391}
392
393static object *
394int_rshift(v, w)
395 intobject *v;
396 register object *w;
397{
398 register long a, b;
399 if (!is_intobject(w)) {
400 err_badarg();
401 return NULL;
402 }
403 a = v->ob_ival;
404 b = ((intobject *)w) -> ob_ival;
Guido van Rossumf3b351f1992-01-14 18:33:22 +0000405 if (b < 0) {
406 err_setstr(ValueError, "negative shift count");
407 return NULL;
408 }
409 if (a == 0 || b == 0) {
410 INCREF(v);
411 return (object *) v;
412 }
413 if (b >= 32) {
414 if (a < 0)
415 a = -1;
416 else
417 a = 0;
418 }
419 else {
420 if (a < 0)
421 a = ~( ~(unsigned long)a >> b );
422 else
423 a = (unsigned long)a >> b;
424 }
425 return newintobject(a);
Guido van Rossum7928cd71991-10-24 14:59:31 +0000426}
427
428static object *
429int_and(v, w)
430 intobject *v;
431 register object *w;
432{
433 register long a, b;
434 if (!is_intobject(w)) {
435 err_badarg();
436 return NULL;
437 }
438 a = v->ob_ival;
439 b = ((intobject *)w) -> ob_ival;
440 return newintobject(a & b);
441}
442
443static object *
444int_xor(v, w)
445 intobject *v;
446 register object *w;
447{
448 register long a, b;
449 if (!is_intobject(w)) {
450 err_badarg();
451 return NULL;
452 }
453 a = v->ob_ival;
454 b = ((intobject *)w) -> ob_ival;
455 return newintobject(a ^ b);
456}
457
458static object *
459int_or(v, w)
460 intobject *v;
461 register object *w;
462{
463 register long a, b;
464 if (!is_intobject(w)) {
465 err_badarg();
466 return NULL;
467 }
468 a = v->ob_ival;
469 b = ((intobject *)w) -> ob_ival;
470 return newintobject(a | b);
471}
472
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000473static number_methods int_as_number = {
Guido van Rossum00466951991-05-05 20:08:27 +0000474 int_add, /*nb_add*/
475 int_sub, /*nb_subtract*/
476 int_mul, /*nb_multiply*/
477 int_div, /*nb_divide*/
478 int_rem, /*nb_remainder*/
479 int_divmod, /*nb_divmod*/
480 int_pow, /*nb_power*/
481 int_neg, /*nb_negative*/
482 int_pos, /*nb_positive*/
483 int_abs, /*nb_absolute*/
Guido van Rossum0bff0151991-05-14 12:05:32 +0000484 int_nonzero, /*nb_nonzero*/
Guido van Rossum7928cd71991-10-24 14:59:31 +0000485 int_invert, /*nb_invert*/
486 int_lshift, /*nb_lshift*/
487 int_rshift, /*nb_rshift*/
488 int_and, /*nb_and*/
489 int_xor, /*nb_xor*/
490 int_or, /*nb_or*/
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};