blob: 6b983f16c0b045d88a63c250c6a7785b175af356 [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
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 Rossum90933611991-06-07 16:10:43 +0000117static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000118int_print(v, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119 intobject *v;
120 FILE *fp;
121 int flags;
122{
123 fprintf(fp, "%ld", v->ob_ival);
Guido van Rossum90933611991-06-07 16:10:43 +0000124 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125}
126
127static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000128int_repr(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000129 intobject *v;
130{
131 char buf[20];
132 sprintf(buf, "%ld", v->ob_ival);
133 return newstringobject(buf);
134}
135
136static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000137int_compare(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000138 intobject *v, *w;
139{
140 register long i = v->ob_ival;
141 register long j = w->ob_ival;
142 return (i < j) ? -1 : (i > j) ? 1 : 0;
143}
144
145static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000146int_add(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000147 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000148 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149{
150 register long a, b, x;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000152 b = w->ob_ival;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153 x = a + b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000154 if ((x^a) < 0 && (x^b) < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000155 return err_ovf("integer addition");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156 return newintobject(x);
157}
158
159static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000160int_sub(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000161 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000162 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163{
164 register long a, b, x;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000166 b = w->ob_ival;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000167 x = a - b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000168 if ((x^a) < 0 && (x^~b) < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000169 return err_ovf("integer subtraction");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000170 return newintobject(x);
171}
172
173static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000174int_mul(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000175 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000176 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177{
178 register long a, b;
179 double x;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000181 b = w->ob_ival;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182 x = (double)a * (double)b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000183 if (x > 0x7fffffff || x < (double) (long) 0x80000000)
Guido van Rossum3a628451991-12-10 13:57:36 +0000184 return err_ovf("integer multiplication");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000185 return newintobject(a * b);
186}
187
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000188static int
189i_divmod(x, y, p_xdivy, p_xmody)
190 register intobject *x, *y;
191 long *p_xdivy, *p_xmody;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192{
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000193 long xi = x->ob_ival;
194 long yi = y->ob_ival;
195 long xdivy, xmody;
196
197 if (yi == 0) {
198 err_setstr(ZeroDivisionError, "integer division or modulo");
199 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200 }
Guido van Rossum00466951991-05-05 20:08:27 +0000201 if (yi < 0) {
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000202 if (xi < 0)
203 xdivy = -xi / -yi;
204 else
205 xdivy = - (xi / -yi);
Guido van Rossum00466951991-05-05 20:08:27 +0000206 }
207 else {
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000208 if (xi < 0)
209 xdivy = - (-xi / yi);
210 else
211 xdivy = xi / yi;
Guido van Rossum00466951991-05-05 20:08:27 +0000212 }
213 xmody = xi - xdivy*yi;
214 if (xmody < 0 && yi > 0 || xmody > 0 && yi < 0) {
215 xmody += yi;
216 xdivy -= 1;
217 }
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000218 *p_xdivy = xdivy;
219 *p_xmody = xmody;
220 return 0;
221}
222
223static object *
224int_div(x, y)
225 intobject *x;
226 intobject *y;
227{
228 long d, m;
229 if (i_divmod(x, y, &d, &m) < 0)
230 return NULL;
231 return newintobject(d);
232}
233
234static object *
235int_mod(x, y)
236 intobject *x;
237 intobject *y;
238{
239 long d, m;
240 if (i_divmod(x, y, &d, &m) < 0)
241 return NULL;
242 newintobject(m);
243}
244
245static object *
246int_divmod(x, y)
247 intobject *x;
248 intobject *y;
249{
250 object *v, *v0, *v1;
251 long d, m;
252 if (i_divmod(x, y, &d, &m) < 0)
253 return NULL;
Guido van Rossum00466951991-05-05 20:08:27 +0000254 v = newtupleobject(2);
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000255 v0 = newintobject(d);
256 v1 = newintobject(m);
Guido van Rossum00466951991-05-05 20:08:27 +0000257 if (v == NULL || v0 == NULL || v1 == NULL ||
258 settupleitem(v, 0, v0) != 0 ||
259 settupleitem(v, 1, v1) != 0) {
260 XDECREF(v);
261 XDECREF(v0);
262 XDECREF(v1);
263 v = NULL;
264 }
265 return v;
266}
267
268static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000269int_pow(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000271 intobject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000272{
273 register long iv, iw, ix;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274 iv = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000275 iw = w->ob_ival;
Guido van Rossum00466951991-05-05 20:08:27 +0000276 if (iw < 0) {
Guido van Rossum3a628451991-12-10 13:57:36 +0000277 err_setstr(ValueError, "integer to the negative power");
Guido van Rossum00466951991-05-05 20:08:27 +0000278 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279 }
Guido van Rossum00466951991-05-05 20:08:27 +0000280 ix = 1;
281 while (--iw >= 0) {
282 long prev = ix;
283 ix = ix * iv;
284 if (iv == 0)
285 break; /* 0 to some power -- avoid ix / 0 */
286 if (ix / iv != prev)
Guido van Rossum3a628451991-12-10 13:57:36 +0000287 return err_ovf("integer pow()");
Guido van Rossum00466951991-05-05 20:08:27 +0000288 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289 return newintobject(ix);
290}
291
292static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000293int_neg(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294 intobject *v;
295{
296 register long a, x;
297 a = v->ob_ival;
298 x = -a;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000299 if (a < 0 && x < 0)
Guido van Rossum3a628451991-12-10 13:57:36 +0000300 return err_ovf("integer negation");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301 return newintobject(x);
302}
303
304static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000305int_pos(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306 intobject *v;
307{
308 INCREF(v);
309 return (object *)v;
310}
311
Guido van Rossum00466951991-05-05 20:08:27 +0000312static object *
313int_abs(v)
314 intobject *v;
315{
316 if (v->ob_ival >= 0)
317 return int_pos(v);
318 else
319 return int_neg(v);
320}
321
Guido van Rossum0bff0151991-05-14 12:05:32 +0000322static int
323int_nonzero(v)
324 intobject *v;
325{
326 return v->ob_ival != 0;
327}
328
Guido van Rossum7928cd71991-10-24 14:59:31 +0000329static object *
330int_invert(v)
331 intobject *v;
332{
333 return newintobject(~v->ob_ival);
334}
335
336static object *
337int_lshift(v, w)
338 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000339 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000340{
341 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000342 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000343 b = w->ob_ival;
Guido van Rossumf3b351f1992-01-14 18:33:22 +0000344 if (b < 0) {
345 err_setstr(ValueError, "negative shift count");
346 return NULL;
347 }
348 if (a == 0 || b == 0) {
349 INCREF(v);
350 return (object *) v;
351 }
352 if (b >= 32) {
353 return newintobject(0L);
354 }
355 a = (unsigned long)a << b;
356 return newintobject(a);
Guido van Rossum7928cd71991-10-24 14:59:31 +0000357}
358
359static object *
360int_rshift(v, w)
361 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000362 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000363{
364 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000365 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000366 b = w->ob_ival;
Guido van Rossumf3b351f1992-01-14 18:33:22 +0000367 if (b < 0) {
368 err_setstr(ValueError, "negative shift count");
369 return NULL;
370 }
371 if (a == 0 || b == 0) {
372 INCREF(v);
373 return (object *) v;
374 }
375 if (b >= 32) {
376 if (a < 0)
377 a = -1;
378 else
379 a = 0;
380 }
381 else {
382 if (a < 0)
383 a = ~( ~(unsigned long)a >> b );
384 else
385 a = (unsigned long)a >> b;
386 }
387 return newintobject(a);
Guido van Rossum7928cd71991-10-24 14:59:31 +0000388}
389
390static object *
391int_and(v, w)
392 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000393 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000394{
395 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000396 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000397 b = w->ob_ival;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000398 return newintobject(a & b);
399}
400
401static object *
402int_xor(v, w)
403 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000404 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000405{
406 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000407 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000408 b = w->ob_ival;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000409 return newintobject(a ^ b);
410}
411
412static object *
413int_or(v, w)
414 intobject *v;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000415 intobject *w;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000416{
417 register long a, b;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000418 a = v->ob_ival;
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000419 b = w->ob_ival;
Guido van Rossum7928cd71991-10-24 14:59:31 +0000420 return newintobject(a | b);
421}
422
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000423static number_methods int_as_number = {
Guido van Rossum00466951991-05-05 20:08:27 +0000424 int_add, /*nb_add*/
425 int_sub, /*nb_subtract*/
426 int_mul, /*nb_multiply*/
427 int_div, /*nb_divide*/
Guido van Rossum2b16a6f1992-01-19 16:28:51 +0000428 int_mod, /*nb_remainder*/
Guido van Rossum00466951991-05-05 20:08:27 +0000429 int_divmod, /*nb_divmod*/
430 int_pow, /*nb_power*/
431 int_neg, /*nb_negative*/
432 int_pos, /*nb_positive*/
433 int_abs, /*nb_absolute*/
Guido van Rossum0bff0151991-05-14 12:05:32 +0000434 int_nonzero, /*nb_nonzero*/
Guido van Rossum7928cd71991-10-24 14:59:31 +0000435 int_invert, /*nb_invert*/
436 int_lshift, /*nb_lshift*/
437 int_rshift, /*nb_rshift*/
438 int_and, /*nb_and*/
439 int_xor, /*nb_xor*/
440 int_or, /*nb_or*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000441};
442
443typeobject Inttype = {
444 OB_HEAD_INIT(&Typetype)
445 0,
446 "int",
447 sizeof(intobject),
448 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000449 int_dealloc, /*tp_dealloc*/
450 int_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000451 0, /*tp_getattr*/
452 0, /*tp_setattr*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000453 int_compare, /*tp_compare*/
454 int_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455 &int_as_number, /*tp_as_number*/
456 0, /*tp_as_sequence*/
457 0, /*tp_as_mapping*/
458};