blob: eeb403885a9e4c7924e6d4b357a0c517d5bc3319 [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 *
42err_ovf()
43{
Guido van Rossum5c52b6a1990-10-21 22:11:03 +000044 err_setstr(OverflowError, "integer overflow");
Guido van Rossum165e67e1990-10-14 20:02:26 +000045 return NULL;
46}
47
48static object *
49err_zdiv()
50{
Guido van Rossum5c52b6a1990-10-21 22:11:03 +000051 err_setstr(ZeroDivisionError, "integer division by zero");
Guido van Rossum165e67e1990-10-14 20:02:26 +000052 return NULL;
53}
54
Guido van Rossum3f5da241990-12-20 15:06:42 +000055/* Integers are quite normal objects, to make object handling uniform.
56 (Using odd pointers to represent integers would save much space
57 but require extra checks for this special case throughout the code.)
58 Since, a typical Python program spends much of its time allocating
59 and deallocating integers, these operations should be very fast.
60 Therefore we use a dedicated allocation scheme with a much lower
61 overhead (in space and time) than straight malloc(): a simple
62 dedicated free list, filled when necessary with memory from malloc().
63*/
64
65#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
66#define N_INTOBJECTS (BLOCK_SIZE / sizeof(intobject))
67
68static intobject *
69fill_free_list()
70{
71 intobject *p, *q;
72 p = NEW(intobject, N_INTOBJECTS);
73 if (p == NULL)
74 return (intobject *)err_nomem();
75 q = p + N_INTOBJECTS;
76 while (--q > p)
77 *(intobject **)q = q-1;
78 *(intobject **)q = NULL;
79 return p + N_INTOBJECTS - 1;
80}
81
82static intobject *free_list = NULL;
83
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000084object *
85newintobject(ival)
86 long ival;
87{
Guido van Rossum3f5da241990-12-20 15:06:42 +000088 register intobject *v;
89 if (free_list == NULL) {
90 if ((free_list = fill_free_list()) == NULL)
91 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092 }
Guido van Rossum3f5da241990-12-20 15:06:42 +000093 v = free_list;
94 free_list = *(intobject **)free_list;
95 NEWREF(v);
96 v->ob_type = &Inttype;
97 v->ob_ival = ival;
98 return (object *) v;
99}
100
101static void
102int_dealloc(v)
103 intobject *v;
104{
105 *(intobject **)v = free_list;
106 free_list = v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107}
108
109long
110getintvalue(op)
111 register object *op;
112{
113 if (!is_intobject(op)) {
Guido van Rossum5c52b6a1990-10-21 22:11:03 +0000114 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115 return -1;
116 }
117 else
118 return ((intobject *)op) -> ob_ival;
119}
120
121/* Methods */
122
123static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000124int_print(v, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125 intobject *v;
126 FILE *fp;
127 int flags;
128{
129 fprintf(fp, "%ld", v->ob_ival);
130}
131
132static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000133int_repr(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 intobject *v;
135{
136 char buf[20];
137 sprintf(buf, "%ld", v->ob_ival);
138 return newstringobject(buf);
139}
140
141static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000142int_compare(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143 intobject *v, *w;
144{
145 register long i = v->ob_ival;
146 register long j = w->ob_ival;
147 return (i < j) ? -1 : (i > j) ? 1 : 0;
148}
149
150static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000151int_add(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152 intobject *v;
153 register object *w;
154{
155 register long a, b, x;
156 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000157 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000158 return NULL;
159 }
160 a = v->ob_ival;
161 b = ((intobject *)w) -> ob_ival;
162 x = a + b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000163 if ((x^a) < 0 && (x^b) < 0)
164 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165 return newintobject(x);
166}
167
168static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000169int_sub(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000170 intobject *v;
171 register object *w;
172{
173 register long a, b, x;
174 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000175 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 return NULL;
177 }
178 a = v->ob_ival;
179 b = ((intobject *)w) -> ob_ival;
180 x = a - b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000181 if ((x^a) < 0 && (x^~b) < 0)
182 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183 return newintobject(x);
184}
185
186static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000187int_mul(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188 intobject *v;
189 register object *w;
190{
191 register long a, b;
192 double x;
193 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000194 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000195 return NULL;
196 }
197 a = v->ob_ival;
198 b = ((intobject *)w) -> ob_ival;
199 x = (double)a * (double)b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000200 if (x > 0x7fffffff || x < (double) (long) 0x80000000)
201 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 return newintobject(a * b);
203}
204
205static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000206int_div(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000207 intobject *v;
208 register object *w;
209{
210 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000211 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212 return NULL;
213 }
Guido van Rossum165e67e1990-10-14 20:02:26 +0000214 if (((intobject *)w) -> ob_ival == 0)
Guido van Rossumabbda161990-10-26 14:58:41 +0000215 return err_zdiv();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000216 return newintobject(v->ob_ival / ((intobject *)w) -> ob_ival);
217}
218
219static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000220int_rem(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000221 intobject *v;
222 register object *w;
223{
224 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000225 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226 return NULL;
227 }
Guido van Rossum165e67e1990-10-14 20:02:26 +0000228 if (((intobject *)w) -> ob_ival == 0)
Guido van Rossumabbda161990-10-26 14:58:41 +0000229 return err_zdiv();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230 return newintobject(v->ob_ival % ((intobject *)w) -> ob_ival);
231}
232
233static object *
Guido van Rossum00466951991-05-05 20:08:27 +0000234int_divmod(x, y)
235 intobject *x;
236 register object *y;
237{
238 object *v, *v0, *v1;
239 long xi, yi, xdivy, xmody;
240 if (!is_intobject(y)) {
241 err_badarg();
242 return NULL;
243 }
244 xi = x->ob_ival;
245 yi = getintvalue(y);
246 if (yi == 0)
247 return err_zdiv();
248 if (yi < 0) {
249 xdivy = -xi / -yi;
250 }
251 else {
252 xdivy = xi / yi;
253 }
254 xmody = xi - xdivy*yi;
255 if (xmody < 0 && yi > 0 || xmody > 0 && yi < 0) {
256 xmody += yi;
257 xdivy -= 1;
258 }
259 v = newtupleobject(2);
260 v0 = newintobject(xdivy);
261 v1 = newintobject(xmody);
262 if (v == NULL || v0 == NULL || v1 == NULL ||
263 settupleitem(v, 0, v0) != 0 ||
264 settupleitem(v, 1, v1) != 0) {
265 XDECREF(v);
266 XDECREF(v0);
267 XDECREF(v1);
268 v = NULL;
269 }
270 return v;
271}
272
273static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000274int_pow(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000275 intobject *v;
276 register object *w;
277{
278 register long iv, iw, ix;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000280 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281 return NULL;
282 }
283 iv = v->ob_ival;
284 iw = ((intobject *)w)->ob_ival;
Guido van Rossum00466951991-05-05 20:08:27 +0000285 if (iw < 0) {
286 err_setstr(RuntimeError, "integer to the negative power");
287 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 }
Guido van Rossum00466951991-05-05 20:08:27 +0000289 ix = 1;
290 while (--iw >= 0) {
291 long prev = ix;
292 ix = ix * iv;
293 if (iv == 0)
294 break; /* 0 to some power -- avoid ix / 0 */
295 if (ix / iv != prev)
296 return err_ovf();
297 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298 return newintobject(ix);
299}
300
301static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000302int_neg(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000303 intobject *v;
304{
305 register long a, x;
306 a = v->ob_ival;
307 x = -a;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000308 if (a < 0 && x < 0)
309 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310 return newintobject(x);
311}
312
313static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000314int_pos(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315 intobject *v;
316{
317 INCREF(v);
318 return (object *)v;
319}
320
Guido van Rossum00466951991-05-05 20:08:27 +0000321static object *
322int_abs(v)
323 intobject *v;
324{
325 if (v->ob_ival >= 0)
326 return int_pos(v);
327 else
328 return int_neg(v);
329}
330
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331static number_methods int_as_number = {
Guido van Rossum00466951991-05-05 20:08:27 +0000332 int_add, /*nb_add*/
333 int_sub, /*nb_subtract*/
334 int_mul, /*nb_multiply*/
335 int_div, /*nb_divide*/
336 int_rem, /*nb_remainder*/
337 int_divmod, /*nb_divmod*/
338 int_pow, /*nb_power*/
339 int_neg, /*nb_negative*/
340 int_pos, /*nb_positive*/
341 int_abs, /*nb_absolute*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000342};
343
344typeobject Inttype = {
345 OB_HEAD_INIT(&Typetype)
346 0,
347 "int",
348 sizeof(intobject),
349 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000350 int_dealloc, /*tp_dealloc*/
351 int_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000352 0, /*tp_getattr*/
353 0, /*tp_setattr*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000354 int_compare, /*tp_compare*/
355 int_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000356 &int_as_number, /*tp_as_number*/
357 0, /*tp_as_sequence*/
358 0, /*tp_as_mapping*/
359};