blob: 6c700e8b228924c3d4c2b72a96825fc6e14baba4 [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 Rossum3f5da241990-12-20 15:06:42 +0000234int_pow(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235 intobject *v;
236 register object *w;
237{
238 register long iv, iw, ix;
239 register int neg;
240 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000241 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242 return NULL;
243 }
244 iv = v->ob_ival;
245 iw = ((intobject *)w)->ob_ival;
246 neg = 0;
247 if (iw < 0)
248 neg = 1, iw = -iw;
249 ix = 1;
250 for (; iw > 0; iw--)
251 ix = ix * iv;
252 if (neg) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000253 if (ix == 0)
Guido van Rossumabbda161990-10-26 14:58:41 +0000254 return err_zdiv();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000255 ix = 1/ix;
256 }
257 /* XXX How to check for overflow? */
258 return newintobject(ix);
259}
260
261static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000262int_neg(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263 intobject *v;
264{
265 register long a, x;
266 a = v->ob_ival;
267 x = -a;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000268 if (a < 0 && x < 0)
269 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270 return newintobject(x);
271}
272
273static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000274int_pos(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000275 intobject *v;
276{
277 INCREF(v);
278 return (object *)v;
279}
280
281static number_methods int_as_number = {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000282 int_add, /*tp_add*/
283 int_sub, /*tp_subtract*/
284 int_mul, /*tp_multiply*/
285 int_div, /*tp_divide*/
286 int_rem, /*tp_remainder*/
287 int_pow, /*tp_power*/
288 int_neg, /*tp_negate*/
289 int_pos, /*tp_plus*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290};
291
292typeobject Inttype = {
293 OB_HEAD_INIT(&Typetype)
294 0,
295 "int",
296 sizeof(intobject),
297 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000298 int_dealloc, /*tp_dealloc*/
299 int_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300 0, /*tp_getattr*/
301 0, /*tp_setattr*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000302 int_compare, /*tp_compare*/
303 int_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 &int_as_number, /*tp_as_number*/
305 0, /*tp_as_sequence*/
306 0, /*tp_as_mapping*/
307};