Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(92)

Side by Side Diff: Objects/longobject.c

Issue 14105: [issue4258] Use 30-bit digits instead of 15-bit digits for Python integers. (Closed) Base URL: http://svn.python.org/view/*checkout*/python/branches/py3k/
Patch Set: Created 16 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 » » /* XXX benchmark this! Is is worth keeping? */
Martin v. Löwis 2009/02/17 22:39:18 Why not PyLong_FromLongLong if available (no speci
dickinsm 2009/02/18 17:06:33 Yes, PyLong_FromLongLong would make sense. If thi
2869 » » r = PyLong_FromLong(MEDIUM_VALUE(a)*MEDIUM_VALUE(b)); 2873 » » twodigits absz;
2870 » » return r; 2874 » » int sign;
2875 » » sign = Py_SIZE(a) * Py_SIZE(b);
2876 » » if (sign == 0)
2877 » » » return PyLong_FromLong(0L);
2878 » » absz = (twodigits)a->ob_digit[0] * b->ob_digit[0];
2879 » » if (absz < PyLong_BASE) {
2880 » » » CHECK_SMALL_INT((sdigit)(sign*absz));
2881 » » » z = _PyLong_New(1);
2882 » » » if (z != NULL) {
2883 » » » » Py_SIZE(z) = sign;
2884 » » » » z->ob_digit[0] = (digit)absz;
2885 » » » }
2886 » » }
2887 » » else {
2888 » » » z = _PyLong_New(2);
2889 » » » if (z != NULL) {
2890 » » » » Py_SIZE(z) = 2*sign;
2891 » » » » z->ob_digit[0] = (digit)(absz & PyLong_MASK);
2892 » » » » assert(absz >>= 2*PyLong_SHIFT == 0);
2893 » » » » z->ob_digit[1] = (digit)(absz >> PyLong_SHIFT);
2894 » » » }
2895 » » }
2896 » » return (PyObject *)z;
2871 } 2897 }
2872 2898
2873 z = k_mul(a, b); 2899 z = k_mul(a, b);
2874 /* Negate if exactly one of the inputs is negative. */ 2900 /* Negate if exactly one of the inputs is negative. */
2875 if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) 2901 if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z)
2876 NEGATE(z); 2902 NEGATE(z);
2877 return (PyObject *)z; 2903 return (PyObject *)z;
2878 } 2904 }
2879 2905
2880 /* The / and % operators are now defined in terms of divmod(). 2906 /* The / and % operators are now defined in terms of divmod().
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3984 0, /* tp_dict */ 4010 0, /* tp_dict */
3985 0, /* tp_descr_get */ 4011 0, /* tp_descr_get */
3986 0, /* tp_descr_set */ 4012 0, /* tp_descr_set */
3987 0, /* tp_dictoffset */ 4013 0, /* tp_dictoffset */
3988 0, /* tp_init */ 4014 0, /* tp_init */
3989 0, /* tp_alloc */ 4015 0, /* tp_alloc */
3990 long_new, /* tp_new */ 4016 long_new, /* tp_new */
3991 PyObject_Del, /* tp_free */ 4017 PyObject_Del, /* tp_free */
3992 }; 4018 };
3993 4019
4020 static PyTypeObject Int_InfoType;
4021
4022 PyDoc_STRVAR(int_info__doc__,
4023 "sys.int_info\n\
4024 \n\
4025 A struct sequence that holds information about Python's\n\
4026 internal representation of integers. The attributes are read only.");
4027
4028 static PyStructSequence_Field int_info_fields[] = {
4029 {"bits_per_digit", "size of a digit in bits"},
4030 {"sizeof_digit", "size in bytes of the C type used to "
4031 "represent a digit"},
4032 {NULL, NULL}
4033 };
4034
4035 static PyStructSequence_Desc int_info_desc = {
4036 "sys.int_info", /* name */
4037 int_info__doc__, /* doc */
4038 int_info_fields, /* fields */
4039 2 /* number of fields */
4040 };
4041
4042 PyObject *
4043 PyLong_GetInfo(void)
4044 {
4045 PyObject* int_info;
4046 int field = 0;
4047 int_info = PyStructSequence_New(&Int_InfoType);
4048 if (int_info == NULL)
4049 return NULL;
4050 PyStructSequence_SET_ITEM(int_info, field++, PyLong_FromLong(PyLong_SHIF T));
4051 PyStructSequence_SET_ITEM(int_info, field++, PyLong_FromLong(sizeof(digi t)));
4052 if (PyErr_Occurred()) {
4053 Py_CLEAR(int_info);
4054 return NULL;
4055 }
4056 return int_info;
4057 }
4058
3994 int 4059 int
3995 _PyLong_Init(void) 4060 _PyLong_Init(void)
3996 { 4061 {
3997 #if NSMALLNEGINTS + NSMALLPOSINTS > 0 4062 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
3998 int ival, size; 4063 int ival, size;
3999 PyLongObject *v = small_ints; 4064 PyLongObject *v = small_ints;
4000 4065
4001 for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) { 4066 for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) {
4002 size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); 4067 size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
4003 if (Py_TYPE(v) == &PyLong_Type) { 4068 if (Py_TYPE(v) == &PyLong_Type) {
(...skipping 12 matching lines...) Expand all
4016 assert(Py_SIZE(op) == size); 4081 assert(Py_SIZE(op) == size);
4017 assert(v->ob_digit[0] == abs(ival)); 4082 assert(v->ob_digit[0] == abs(ival));
4018 } 4083 }
4019 else { 4084 else {
4020 PyObject_INIT(v, &PyLong_Type); 4085 PyObject_INIT(v, &PyLong_Type);
4021 } 4086 }
4022 Py_SIZE(v) = size; 4087 Py_SIZE(v) = size;
4023 v->ob_digit[0] = abs(ival); 4088 v->ob_digit[0] = abs(ival);
4024 } 4089 }
4025 #endif 4090 #endif
4091 /* initialize int_info */
4092 if (Int_InfoType.tp_name == 0)
4093 PyStructSequence_InitType(&Int_InfoType, &int_info_desc);
4094
4026 return 1; 4095 return 1;
4027 } 4096 }
4028 4097
4029 void 4098 void
4030 PyLong_Fini(void) 4099 PyLong_Fini(void)
4031 { 4100 {
4032 /* Integers are currently statically allocated. Py_DECREF is not 4101 /* Integers are currently statically allocated. Py_DECREF is not
4033 needed, but Python must forget about the reference or multiple 4102 needed, but Python must forget about the reference or multiple
4034 reinitializations will fail. */ 4103 reinitializations will fail. */
4035 #if NSMALLNEGINTS + NSMALLPOSINTS > 0 4104 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
4036 int i; 4105 int i;
4037 PyLongObject *v = small_ints; 4106 PyLongObject *v = small_ints;
4038 for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) { 4107 for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) {
4039 _Py_DEC_REFTOTAL; 4108 _Py_DEC_REFTOTAL;
4040 _Py_ForgetReference((PyObject*)v); 4109 _Py_ForgetReference((PyObject*)v);
4041 } 4110 }
4042 #endif 4111 #endif
4043 } 4112 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b