blob: 91c43b97b809c63df844bdcbbbbcaa77c8fe47e1 [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
Guido van Rossum90933611991-06-07 16:10:43 +0000123static int
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);
Guido van Rossum90933611991-06-07 16:10:43 +0000130 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131}
132
133static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000134int_repr(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135 intobject *v;
136{
137 char buf[20];
138 sprintf(buf, "%ld", v->ob_ival);
139 return newstringobject(buf);
140}
141
142static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000143int_compare(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000144 intobject *v, *w;
145{
146 register long i = v->ob_ival;
147 register long j = w->ob_ival;
148 return (i < j) ? -1 : (i > j) ? 1 : 0;
149}
150
151static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000152int_add(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153 intobject *v;
154 register object *w;
155{
156 register long a, b, x;
157 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000158 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159 return NULL;
160 }
161 a = v->ob_ival;
162 b = ((intobject *)w) -> ob_ival;
163 x = a + b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000164 if ((x^a) < 0 && (x^b) < 0)
165 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166 return newintobject(x);
167}
168
169static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000170int_sub(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171 intobject *v;
172 register object *w;
173{
174 register long a, b, x;
175 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000176 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177 return NULL;
178 }
179 a = v->ob_ival;
180 b = ((intobject *)w) -> ob_ival;
181 x = a - b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000182 if ((x^a) < 0 && (x^~b) < 0)
183 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184 return newintobject(x);
185}
186
187static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000188int_mul(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189 intobject *v;
190 register object *w;
191{
192 register long a, b;
193 double x;
194 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000195 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196 return NULL;
197 }
198 a = v->ob_ival;
199 b = ((intobject *)w) -> ob_ival;
200 x = (double)a * (double)b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000201 if (x > 0x7fffffff || x < (double) (long) 0x80000000)
202 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000203 return newintobject(a * b);
204}
205
206static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000207int_div(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208 intobject *v;
209 register object *w;
210{
211 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000212 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213 return NULL;
214 }
Guido van Rossum165e67e1990-10-14 20:02:26 +0000215 if (((intobject *)w) -> ob_ival == 0)
Guido van Rossumabbda161990-10-26 14:58:41 +0000216 return err_zdiv();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217 return newintobject(v->ob_ival / ((intobject *)w) -> ob_ival);
218}
219
220static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000221int_rem(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 intobject *v;
223 register object *w;
224{
225 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000226 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227 return NULL;
228 }
Guido van Rossum165e67e1990-10-14 20:02:26 +0000229 if (((intobject *)w) -> ob_ival == 0)
Guido van Rossumabbda161990-10-26 14:58:41 +0000230 return err_zdiv();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231 return newintobject(v->ob_ival % ((intobject *)w) -> ob_ival);
232}
233
234static object *
Guido van Rossum00466951991-05-05 20:08:27 +0000235int_divmod(x, y)
236 intobject *x;
237 register object *y;
238{
239 object *v, *v0, *v1;
240 long xi, yi, xdivy, xmody;
241 if (!is_intobject(y)) {
242 err_badarg();
243 return NULL;
244 }
245 xi = x->ob_ival;
246 yi = getintvalue(y);
247 if (yi == 0)
248 return err_zdiv();
249 if (yi < 0) {
250 xdivy = -xi / -yi;
251 }
252 else {
253 xdivy = xi / yi;
254 }
255 xmody = xi - xdivy*yi;
256 if (xmody < 0 && yi > 0 || xmody > 0 && yi < 0) {
257 xmody += yi;
258 xdivy -= 1;
259 }
260 v = newtupleobject(2);
261 v0 = newintobject(xdivy);
262 v1 = newintobject(xmody);
263 if (v == NULL || v0 == NULL || v1 == NULL ||
264 settupleitem(v, 0, v0) != 0 ||
265 settupleitem(v, 1, v1) != 0) {
266 XDECREF(v);
267 XDECREF(v0);
268 XDECREF(v1);
269 v = NULL;
270 }
271 return v;
272}
273
274static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000275int_pow(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276 intobject *v;
277 register object *w;
278{
279 register long iv, iw, ix;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000281 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282 return NULL;
283 }
284 iv = v->ob_ival;
285 iw = ((intobject *)w)->ob_ival;
Guido van Rossum00466951991-05-05 20:08:27 +0000286 if (iw < 0) {
287 err_setstr(RuntimeError, "integer to the negative power");
288 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289 }
Guido van Rossum00466951991-05-05 20:08:27 +0000290 ix = 1;
291 while (--iw >= 0) {
292 long prev = ix;
293 ix = ix * iv;
294 if (iv == 0)
295 break; /* 0 to some power -- avoid ix / 0 */
296 if (ix / iv != prev)
297 return err_ovf();
298 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299 return newintobject(ix);
300}
301
302static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000303int_neg(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 intobject *v;
305{
306 register long a, x;
307 a = v->ob_ival;
308 x = -a;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000309 if (a < 0 && x < 0)
310 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311 return newintobject(x);
312}
313
314static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000315int_pos(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316 intobject *v;
317{
318 INCREF(v);
319 return (object *)v;
320}
321
Guido van Rossum00466951991-05-05 20:08:27 +0000322static object *
323int_abs(v)
324 intobject *v;
325{
326 if (v->ob_ival >= 0)
327 return int_pos(v);
328 else
329 return int_neg(v);
330}
331
Guido van Rossum0bff0151991-05-14 12:05:32 +0000332static int
333int_nonzero(v)
334 intobject *v;
335{
336 return v->ob_ival != 0;
337}
338
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000339static number_methods int_as_number = {
Guido van Rossum00466951991-05-05 20:08:27 +0000340 int_add, /*nb_add*/
341 int_sub, /*nb_subtract*/
342 int_mul, /*nb_multiply*/
343 int_div, /*nb_divide*/
344 int_rem, /*nb_remainder*/
345 int_divmod, /*nb_divmod*/
346 int_pow, /*nb_power*/
347 int_neg, /*nb_negative*/
348 int_pos, /*nb_positive*/
349 int_abs, /*nb_absolute*/
Guido van Rossum0bff0151991-05-14 12:05:32 +0000350 int_nonzero, /*nb_nonzero*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351};
352
353typeobject Inttype = {
354 OB_HEAD_INIT(&Typetype)
355 0,
356 "int",
357 sizeof(intobject),
358 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000359 int_dealloc, /*tp_dealloc*/
360 int_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000361 0, /*tp_getattr*/
362 0, /*tp_setattr*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000363 int_compare, /*tp_compare*/
364 int_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000365 &int_as_number, /*tp_as_number*/
366 0, /*tp_as_sequence*/
367 0, /*tp_as_mapping*/
368};