OLD | NEW |
1 /* Long (arbitrary precision) integer object implementation */ | 1 /* Long (arbitrary precision) integer object implementation */ |
2 | 2 |
3 /* XXX The functional organization of this file is terrible */ | 3 /* XXX The functional organization of this file is terrible */ |
4 | 4 |
5 #include "Python.h" | 5 #include "Python.h" |
6 #include "longintrepr.h" | 6 #include "longintrepr.h" |
| 7 #include "structseq.h" |
7 | 8 |
8 #include <ctype.h> | 9 #include <ctype.h> |
9 #include <stddef.h> | 10 #include <stddef.h> |
10 | 11 |
11 #ifndef NSMALLPOSINTS | 12 #ifndef NSMALLPOSINTS |
12 #define NSMALLPOSINTS 257 | 13 #define NSMALLPOSINTS 257 |
13 #endif | 14 #endif |
14 #ifndef NSMALLNEGINTS | 15 #ifndef NSMALLNEGINTS |
15 #define NSMALLNEGINTS 5 | 16 #define NSMALLNEGINTS 5 |
16 #endif | 17 #endif |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 if (!(abs_ival >> PyLong_SHIFT)) { | 198 if (!(abs_ival >> PyLong_SHIFT)) { |
198 v = _PyLong_New(1); | 199 v = _PyLong_New(1); |
199 if (v) { | 200 if (v) { |
200 Py_SIZE(v) = sign; | 201 Py_SIZE(v) = sign; |
201 v->ob_digit[0] = Py_SAFE_DOWNCAST( | 202 v->ob_digit[0] = Py_SAFE_DOWNCAST( |
202 abs_ival, unsigned long, digit); | 203 abs_ival, unsigned long, digit); |
203 } | 204 } |
204 return (PyObject*)v; | 205 return (PyObject*)v; |
205 } | 206 } |
206 | 207 |
| 208 #if PyLONG_SHIFT==15 |
207 /* 2 digits */ | 209 /* 2 digits */ |
208 if (!(abs_ival >> 2*PyLong_SHIFT)) { | 210 if (!(abs_ival >> 2*PyLong_SHIFT)) { |
209 v = _PyLong_New(2); | 211 v = _PyLong_New(2); |
210 if (v) { | 212 if (v) { |
211 Py_SIZE(v) = 2*sign; | 213 Py_SIZE(v) = 2*sign; |
212 v->ob_digit[0] = Py_SAFE_DOWNCAST( | 214 v->ob_digit[0] = Py_SAFE_DOWNCAST( |
213 abs_ival & PyLong_MASK, unsigned long, digit); | 215 abs_ival & PyLong_MASK, unsigned long, digit); |
214 v->ob_digit[1] = Py_SAFE_DOWNCAST( | 216 v->ob_digit[1] = Py_SAFE_DOWNCAST( |
215 abs_ival >> PyLong_SHIFT, unsigned long, digit); | 217 abs_ival >> PyLong_SHIFT, unsigned long, digit); |
216 } | 218 } |
217 return (PyObject*)v; | 219 return (PyObject*)v; |
218 } | 220 } |
| 221 #endif |
219 | 222 |
220 /* Larger numbers: loop to determine number of digits */ | 223 /* Larger numbers: loop to determine number of digits */ |
221 t = abs_ival; | 224 t = abs_ival; |
222 while (t) { | 225 while (t) { |
223 ++ndigits; | 226 ++ndigits; |
224 t >>= PyLong_SHIFT; | 227 t >>= PyLong_SHIFT; |
225 } | 228 } |
226 v = _PyLong_New(ndigits); | 229 v = _PyLong_New(ndigits); |
227 if (v != NULL) { | 230 if (v != NULL) { |
228 digit *p = v->ob_digit; | 231 digit *p = v->ob_digit; |
(...skipping 2628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2857 return NULL; | 2860 return NULL; |
2858 } | 2861 } |
2859 | 2862 |
2860 static PyObject * | 2863 static PyObject * |
2861 long_mul(PyLongObject *a, PyLongObject *b) | 2864 long_mul(PyLongObject *a, PyLongObject *b) |
2862 { | 2865 { |
2863 PyLongObject *z; | 2866 PyLongObject *z; |
2864 | 2867 |
2865 CHECK_BINOP(a, b); | 2868 CHECK_BINOP(a, b); |
2866 | 2869 |
| 2870 /* fast path for single-digit multiplication */ |
2867 if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { | 2871 if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { |
2868 » » PyObject *r; | 2872 » » stwodigits v = (stwodigits)(MEDIUM_VALUE(a)) * MEDIUM_VALUE(b); |
2869 » » r = PyLong_FromLong(MEDIUM_VALUE(a)*MEDIUM_VALUE(b)); | 2873 #ifdef HAVE_LONG_LONG |
2870 » » return r; | 2874 » » return PyLong_FromLongLong((PY_LONG_LONG)v); |
| 2875 #else |
| 2876 » » /* if we don't have long long then we're almost certainly |
| 2877 » » using 15-bit digits, so v will fit in a long. In the |
| 2878 » » unlikely event that we're using 30-bit digits on a platform |
| 2879 » » without long long, a large v will just cause us to fall |
| 2880 » » through to the general multiplication code below. */ |
| 2881 » » if (v >= LONG_MIN && v <= LONG_MAX) |
| 2882 » » » return PyLong_FromLong((long)v); |
| 2883 #endif |
2871 } | 2884 } |
2872 | 2885 |
2873 z = k_mul(a, b); | 2886 z = k_mul(a, b); |
2874 /* Negate if exactly one of the inputs is negative. */ | 2887 /* Negate if exactly one of the inputs is negative. */ |
2875 if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) | 2888 if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) |
2876 NEGATE(z); | 2889 NEGATE(z); |
2877 return (PyObject *)z; | 2890 return (PyObject *)z; |
2878 } | 2891 } |
2879 | 2892 |
2880 /* The / and % operators are now defined in terms of divmod(). | 2893 /* The / and % operators are now defined in terms of divmod(). |
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3984 0, /* tp_dict */ | 3997 0, /* tp_dict */ |
3985 0, /* tp_descr_get */ | 3998 0, /* tp_descr_get */ |
3986 0, /* tp_descr_set */ | 3999 0, /* tp_descr_set */ |
3987 0, /* tp_dictoffset */ | 4000 0, /* tp_dictoffset */ |
3988 0, /* tp_init */ | 4001 0, /* tp_init */ |
3989 0, /* tp_alloc */ | 4002 0, /* tp_alloc */ |
3990 long_new, /* tp_new */ | 4003 long_new, /* tp_new */ |
3991 PyObject_Del, /* tp_free */ | 4004 PyObject_Del, /* tp_free */ |
3992 }; | 4005 }; |
3993 | 4006 |
| 4007 static PyTypeObject Int_InfoType; |
| 4008 |
| 4009 PyDoc_STRVAR(int_info__doc__, |
| 4010 "sys.int_info\n\ |
| 4011 \n\ |
| 4012 A struct sequence that holds information about Python's\n\ |
| 4013 internal representation of integers. The attributes are read only."); |
| 4014 |
| 4015 static PyStructSequence_Field int_info_fields[] = { |
| 4016 {"bits_per_digit", "size of a digit in bits"}, |
| 4017 {"sizeof_digit", "size in bytes of the C type used to " |
| 4018 "represent a digit"}, |
| 4019 {NULL, NULL} |
| 4020 }; |
| 4021 |
| 4022 static PyStructSequence_Desc int_info_desc = { |
| 4023 "sys.int_info", /* name */ |
| 4024 int_info__doc__, /* doc */ |
| 4025 int_info_fields, /* fields */ |
| 4026 2 /* number of fields */ |
| 4027 }; |
| 4028 |
| 4029 PyObject * |
| 4030 PyLong_GetInfo(void) |
| 4031 { |
| 4032 PyObject* int_info; |
| 4033 int field = 0; |
| 4034 int_info = PyStructSequence_New(&Int_InfoType); |
| 4035 if (int_info == NULL) |
| 4036 return NULL; |
| 4037 PyStructSequence_SET_ITEM(int_info, field++, PyLong_FromLong(PyLong_SHIF
T)); |
| 4038 PyStructSequence_SET_ITEM(int_info, field++, PyLong_FromLong(sizeof(digi
t))); |
| 4039 if (PyErr_Occurred()) { |
| 4040 Py_CLEAR(int_info); |
| 4041 return NULL; |
| 4042 } |
| 4043 return int_info; |
| 4044 } |
| 4045 |
3994 int | 4046 int |
3995 _PyLong_Init(void) | 4047 _PyLong_Init(void) |
3996 { | 4048 { |
3997 #if NSMALLNEGINTS + NSMALLPOSINTS > 0 | 4049 #if NSMALLNEGINTS + NSMALLPOSINTS > 0 |
3998 int ival, size; | 4050 int ival, size; |
3999 PyLongObject *v = small_ints; | 4051 PyLongObject *v = small_ints; |
4000 | 4052 |
4001 for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) { | 4053 for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) { |
4002 size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); | 4054 size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); |
4003 if (Py_TYPE(v) == &PyLong_Type) { | 4055 if (Py_TYPE(v) == &PyLong_Type) { |
(...skipping 12 matching lines...) Expand all Loading... |
4016 assert(Py_SIZE(op) == size); | 4068 assert(Py_SIZE(op) == size); |
4017 assert(v->ob_digit[0] == abs(ival)); | 4069 assert(v->ob_digit[0] == abs(ival)); |
4018 } | 4070 } |
4019 else { | 4071 else { |
4020 PyObject_INIT(v, &PyLong_Type); | 4072 PyObject_INIT(v, &PyLong_Type); |
4021 } | 4073 } |
4022 Py_SIZE(v) = size; | 4074 Py_SIZE(v) = size; |
4023 v->ob_digit[0] = abs(ival); | 4075 v->ob_digit[0] = abs(ival); |
4024 } | 4076 } |
4025 #endif | 4077 #endif |
| 4078 /* initialize int_info */ |
| 4079 if (Int_InfoType.tp_name == 0) |
| 4080 PyStructSequence_InitType(&Int_InfoType, &int_info_desc); |
| 4081 |
4026 return 1; | 4082 return 1; |
4027 } | 4083 } |
4028 | 4084 |
4029 void | 4085 void |
4030 PyLong_Fini(void) | 4086 PyLong_Fini(void) |
4031 { | 4087 { |
4032 /* Integers are currently statically allocated. Py_DECREF is not | 4088 /* Integers are currently statically allocated. Py_DECREF is not |
4033 needed, but Python must forget about the reference or multiple | 4089 needed, but Python must forget about the reference or multiple |
4034 reinitializations will fail. */ | 4090 reinitializations will fail. */ |
4035 #if NSMALLNEGINTS + NSMALLPOSINTS > 0 | 4091 #if NSMALLNEGINTS + NSMALLPOSINTS > 0 |
4036 int i; | 4092 int i; |
4037 PyLongObject *v = small_ints; | 4093 PyLongObject *v = small_ints; |
4038 for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) { | 4094 for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) { |
4039 _Py_DEC_REFTOTAL; | 4095 _Py_DEC_REFTOTAL; |
4040 _Py_ForgetReference((PyObject*)v); | 4096 _Py_ForgetReference((PyObject*)v); |
4041 } | 4097 } |
4042 #endif | 4098 #endif |
4043 } | 4099 } |
OLD | NEW |