| Left: | ||
| Right: |
| 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 » » /* 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |