blob: d70fcef45be5d702357f82540b5cfa8d0555874f [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Integer object implementation */
2
Guido van Rossum3f5da241990-12-20 15:06:42 +00003#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004
5/* Standard Booleans */
Guido van Rossum3f5da241990-12-20 15:06:42 +00006
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007intobject FalseObject = {
8 OB_HEAD_INIT(&Inttype)
9 0
10};
Guido van Rossum3f5da241990-12-20 15:06:42 +000011
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012intobject TrueObject = {
13 OB_HEAD_INIT(&Inttype)
14 1
15};
16
Guido van Rossum165e67e1990-10-14 20:02:26 +000017static object *
18err_ovf()
19{
Guido van Rossum5c52b6a1990-10-21 22:11:03 +000020 err_setstr(OverflowError, "integer overflow");
Guido van Rossum165e67e1990-10-14 20:02:26 +000021 return NULL;
22}
23
24static object *
25err_zdiv()
26{
Guido van Rossum5c52b6a1990-10-21 22:11:03 +000027 err_setstr(ZeroDivisionError, "integer division by zero");
Guido van Rossum165e67e1990-10-14 20:02:26 +000028 return NULL;
29}
30
Guido van Rossum3f5da241990-12-20 15:06:42 +000031/* Integers are quite normal objects, to make object handling uniform.
32 (Using odd pointers to represent integers would save much space
33 but require extra checks for this special case throughout the code.)
34 Since, a typical Python program spends much of its time allocating
35 and deallocating integers, these operations should be very fast.
36 Therefore we use a dedicated allocation scheme with a much lower
37 overhead (in space and time) than straight malloc(): a simple
38 dedicated free list, filled when necessary with memory from malloc().
39*/
40
41#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
42#define N_INTOBJECTS (BLOCK_SIZE / sizeof(intobject))
43
44static intobject *
45fill_free_list()
46{
47 intobject *p, *q;
48 p = NEW(intobject, N_INTOBJECTS);
49 if (p == NULL)
50 return (intobject *)err_nomem();
51 q = p + N_INTOBJECTS;
52 while (--q > p)
53 *(intobject **)q = q-1;
54 *(intobject **)q = NULL;
55 return p + N_INTOBJECTS - 1;
56}
57
58static intobject *free_list = NULL;
59
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060object *
61newintobject(ival)
62 long ival;
63{
Guido van Rossum3f5da241990-12-20 15:06:42 +000064 register intobject *v;
65 if (free_list == NULL) {
66 if ((free_list = fill_free_list()) == NULL)
67 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000068 }
Guido van Rossum3f5da241990-12-20 15:06:42 +000069 v = free_list;
70 free_list = *(intobject **)free_list;
71 NEWREF(v);
72 v->ob_type = &Inttype;
73 v->ob_ival = ival;
74 return (object *) v;
75}
76
77static void
78int_dealloc(v)
79 intobject *v;
80{
81 *(intobject **)v = free_list;
82 free_list = v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083}
84
85long
86getintvalue(op)
87 register object *op;
88{
89 if (!is_intobject(op)) {
Guido van Rossum5c52b6a1990-10-21 22:11:03 +000090 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091 return -1;
92 }
93 else
94 return ((intobject *)op) -> ob_ival;
95}
96
97/* Methods */
98
99static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000100int_print(v, fp, flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101 intobject *v;
102 FILE *fp;
103 int flags;
104{
105 fprintf(fp, "%ld", v->ob_ival);
106}
107
108static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000109int_repr(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 intobject *v;
111{
112 char buf[20];
113 sprintf(buf, "%ld", v->ob_ival);
114 return newstringobject(buf);
115}
116
117static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000118int_compare(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119 intobject *v, *w;
120{
121 register long i = v->ob_ival;
122 register long j = w->ob_ival;
123 return (i < j) ? -1 : (i > j) ? 1 : 0;
124}
125
126static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000127int_add(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000128 intobject *v;
129 register object *w;
130{
131 register long a, b, x;
132 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000133 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 return NULL;
135 }
136 a = v->ob_ival;
137 b = ((intobject *)w) -> ob_ival;
138 x = a + b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000139 if ((x^a) < 0 && (x^b) < 0)
140 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000141 return newintobject(x);
142}
143
144static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000145int_sub(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000146 intobject *v;
147 register object *w;
148{
149 register long a, b, x;
150 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000151 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152 return NULL;
153 }
154 a = v->ob_ival;
155 b = ((intobject *)w) -> ob_ival;
156 x = a - b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000157 if ((x^a) < 0 && (x^~b) < 0)
158 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159 return newintobject(x);
160}
161
162static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000163int_mul(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164 intobject *v;
165 register object *w;
166{
167 register long a, b;
168 double x;
169 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000170 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171 return NULL;
172 }
173 a = v->ob_ival;
174 b = ((intobject *)w) -> ob_ival;
175 x = (double)a * (double)b;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000176 if (x > 0x7fffffff || x < (double) (long) 0x80000000)
177 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 return newintobject(a * b);
179}
180
181static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000182int_div(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183 intobject *v;
184 register object *w;
185{
186 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000187 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188 return NULL;
189 }
Guido van Rossum165e67e1990-10-14 20:02:26 +0000190 if (((intobject *)w) -> ob_ival == 0)
Guido van Rossumabbda161990-10-26 14:58:41 +0000191 return err_zdiv();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192 return newintobject(v->ob_ival / ((intobject *)w) -> ob_ival);
193}
194
195static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000196int_rem(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 intobject *v;
198 register object *w;
199{
200 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000201 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 return NULL;
203 }
Guido van Rossum165e67e1990-10-14 20:02:26 +0000204 if (((intobject *)w) -> ob_ival == 0)
Guido van Rossumabbda161990-10-26 14:58:41 +0000205 return err_zdiv();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206 return newintobject(v->ob_ival % ((intobject *)w) -> ob_ival);
207}
208
209static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000210int_pow(v, w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211 intobject *v;
212 register object *w;
213{
214 register long iv, iw, ix;
215 register int neg;
216 if (!is_intobject(w)) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000217 err_badarg();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218 return NULL;
219 }
220 iv = v->ob_ival;
221 iw = ((intobject *)w)->ob_ival;
222 neg = 0;
223 if (iw < 0)
224 neg = 1, iw = -iw;
225 ix = 1;
226 for (; iw > 0; iw--)
227 ix = ix * iv;
228 if (neg) {
Guido van Rossum165e67e1990-10-14 20:02:26 +0000229 if (ix == 0)
Guido van Rossumabbda161990-10-26 14:58:41 +0000230 return err_zdiv();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231 ix = 1/ix;
232 }
233 /* XXX How to check for overflow? */
234 return newintobject(ix);
235}
236
237static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000238int_neg(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000239 intobject *v;
240{
241 register long a, x;
242 a = v->ob_ival;
243 x = -a;
Guido van Rossum165e67e1990-10-14 20:02:26 +0000244 if (a < 0 && x < 0)
245 return err_ovf();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000246 return newintobject(x);
247}
248
249static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000250int_pos(v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 intobject *v;
252{
253 INCREF(v);
254 return (object *)v;
255}
256
257static number_methods int_as_number = {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000258 int_add, /*tp_add*/
259 int_sub, /*tp_subtract*/
260 int_mul, /*tp_multiply*/
261 int_div, /*tp_divide*/
262 int_rem, /*tp_remainder*/
263 int_pow, /*tp_power*/
264 int_neg, /*tp_negate*/
265 int_pos, /*tp_plus*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000266};
267
268typeobject Inttype = {
269 OB_HEAD_INIT(&Typetype)
270 0,
271 "int",
272 sizeof(intobject),
273 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000274 int_dealloc, /*tp_dealloc*/
275 int_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276 0, /*tp_getattr*/
277 0, /*tp_setattr*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000278 int_compare, /*tp_compare*/
279 int_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280 &int_as_number, /*tp_as_number*/
281 0, /*tp_as_sequence*/
282 0, /*tp_as_mapping*/
283};