blob: 181cb4f42114b3b8b771425b2ea6494719282955 [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;
378 return newintobject((unsigned long)a << b);
379}
380
381static object *
382int_rshift(v, w)
383 intobject *v;
384 register object *w;
385{
386 register long a, b;
387 if (!is_intobject(w)) {
388 err_badarg();
389 return NULL;
390 }
391 a = v->ob_ival;
392 b = ((intobject *)w) -> ob_ival;
393 return newintobject((unsigned long)a >> b);
394}
395
396static object *
397int_and(v, w)
398 intobject *v;
399 register object *w;
400{
401 register long a, b;
402 if (!is_intobject(w)) {
403 err_badarg();
404 return NULL;
405 }
406 a = v->ob_ival;
407 b = ((intobject *)w) -> ob_ival;
408 return newintobject(a & b);
409}
410
411static object *
412int_xor(v, w)
413 intobject *v;
414 register object *w;
415{
416 register long a, b;
417 if (!is_intobject(w)) {
418 err_badarg();
419 return NULL;
420 }
421 a = v->ob_ival;
422 b = ((intobject *)w) -> ob_ival;
423 return newintobject(a ^ b);
424}
425
426static object *
427int_or(v, w)
428 intobject *v;
429 register object *w;
430{
431 register long a, b;
432 if (!is_intobject(w)) {
433 err_badarg();
434 return NULL;
435 }
436 a = v->ob_ival;
437 b = ((intobject *)w) -> ob_ival;
438 return newintobject(a | b);
439}
440
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000441static number_methods int_as_number = {
Guido van Rossum00466951991-05-05 20:08:27 +0000442 int_add, /*nb_add*/
443 int_sub, /*nb_subtract*/
444 int_mul, /*nb_multiply*/
445 int_div, /*nb_divide*/
446 int_rem, /*nb_remainder*/
447 int_divmod, /*nb_divmod*/
448 int_pow, /*nb_power*/
449 int_neg, /*nb_negative*/
450 int_pos, /*nb_positive*/
451 int_abs, /*nb_absolute*/
Guido van Rossum0bff0151991-05-14 12:05:32 +0000452 int_nonzero, /*nb_nonzero*/
Guido van Rossum7928cd71991-10-24 14:59:31 +0000453 int_invert, /*nb_invert*/
454 int_lshift, /*nb_lshift*/
455 int_rshift, /*nb_rshift*/
456 int_and, /*nb_and*/
457 int_xor, /*nb_xor*/
458 int_or, /*nb_or*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459};
460
461typeobject Inttype = {
462 OB_HEAD_INIT(&Typetype)
463 0,
464 "int",
465 sizeof(intobject),
466 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000467 int_dealloc, /*tp_dealloc*/
468 int_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000469 0, /*tp_getattr*/
470 0, /*tp_setattr*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000471 int_compare, /*tp_compare*/
472 int_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000473 &int_as_number, /*tp_as_number*/
474 0, /*tp_as_sequence*/
475 0, /*tp_as_mapping*/
476};