annotate Objects/longobject.c @ 80661:94de77bd0b4b 2.7

Issue #16194: document imp.load_dynamic problems when read several extension modules from the same binary object file.
author Andrew Svetlov <andrew.svetlov@gmail.com>
date Thu, 29 Nov 2012 19:51:28 +0200
parents 3b484f53f91b
children c0266ba8e4c6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1 /* Long (arbitrary precision) integer object implementation */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2
242
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
3 /* XXX The functional organization of this file is terrible */
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
4
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
5 #include "Python.h"
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
6 #include "longintrepr.h"
52233
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
7 #include "structseq.h"
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
8
53289
8f28ce7b8e69 Issue #3166: Make long -> float (and int -> float) conversions
Mark Dickinson <dickinsm@gmail.com>
parents: 52739
diff changeset
9 #include <float.h>
1837
87364d9e3444 New patches by Andrew to fix various problems
Guido van Rossum <guido@python.org>
parents: 1391
diff changeset
10 #include <ctype.h>
51641
b55a3b5d7008 Issue #5260: Various portability and standards compliance fixes, optimizations
Mark Dickinson <dickinsm@gmail.com>
parents: 51517
diff changeset
11 #include <stddef.h>
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
12
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
13 /* For long multiplication, use the O(N**2) school algorithm unless
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
14 * both operands contain more than KARATSUBA_CUTOFF digits (this
44945
bbc719a8b58b Backport of several functions from Python 3.0 to 2.6 including PyUnicode_FromString, PyUnicode_Format and PyLong_From/AsSsize_t. The functions are partly required for the backport of the bytearray type and _fileio module. They should also make it easier to port C to 3.0.
Christian Heimes <christian@cheimes.de>
parents: 44749
diff changeset
15 * being an internal Python long digit, in base PyLong_BASE).
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
16 */
33325
1768aff92864 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 29641
diff changeset
17 #define KARATSUBA_CUTOFF 70
1768aff92864 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 29641
diff changeset
18 #define KARATSUBA_SQUARE_CUTOFF (2 * KARATSUBA_CUTOFF)
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
19
33327
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
20 /* For exponentiation, use the binary left-to-right algorithm
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
21 * unless the exponent contains more than FIVEARY_CUTOFF digits.
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
22 * In that case, do 5 bits at a time. The potential drawback is that
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
23 * a table of 2**5 intermediate results is computed.
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
24 */
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
25 #define FIVEARY_CUTOFF 8
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
26
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
27 #define ABS(x) ((x) < 0 ? -(x) : (x))
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
28
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
29 #undef MIN
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
30 #undef MAX
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
31 #define MAX(x, y) ((x) < (y) ? (y) : (x))
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
32 #define MIN(x, y) ((x) > (y) ? (y) : (x))
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
33
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
34 #define SIGCHECK(PyTryBlock) \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
35 do { \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
36 if (--_Py_Ticker < 0) { \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
37 _Py_Ticker = _Py_CheckInterval; \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
38 if (PyErr_CheckSignals()) PyTryBlock \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
39 } \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
40 } while(0)
242
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
41
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
42 /* Normalize (remove leading zeros from) a long int object.
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
43 Doesn't attempt to free the storage--in most cases, due to the nature
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
44 of the algorithms used, this could save at most be one word anyway. */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
45
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
46 static PyLongObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
47 long_normalize(register PyLongObject *v)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
48 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
49 Py_ssize_t j = ABS(Py_SIZE(v));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
50 Py_ssize_t i = j;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
51
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
52 while (i > 0 && v->ob_digit[i-1] == 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
53 --i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
54 if (i != j)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
55 Py_SIZE(v) = (Py_SIZE(v) < 0) ? -(i) : i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
56 return v;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
57 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
58
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
59 /* Allocate a new long int object with size digits.
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
60 Return NULL and set exception if we run out of memory. */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
61
51641
b55a3b5d7008 Issue #5260: Various portability and standards compliance fixes, optimizations
Mark Dickinson <dickinsm@gmail.com>
parents: 51517
diff changeset
62 #define MAX_LONG_DIGITS \
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
63 ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit))
51641
b55a3b5d7008 Issue #5260: Various portability and standards compliance fixes, optimizations
Mark Dickinson <dickinsm@gmail.com>
parents: 51517
diff changeset
64
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
65 PyLongObject *
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
66 _PyLong_New(Py_ssize_t size)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
67 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
68 if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
69 PyErr_SetString(PyExc_OverflowError,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
70 "too many digits in integer");
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
71 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
72 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
73 /* coverity[ampersand_in_size] */
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
74 /* XXX(nnorwitz): PyObject_NEW_VAR / _PyObject_VAR_SIZE need to detect
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
75 overflow */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
76 return PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
77 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
78
19837
5158e4789459 SF bug #460020: bug or feature: unicode() and subclasses.
Tim Peters <tim.peters@gmail.com>
parents: 19787
diff changeset
79 PyObject *
5158e4789459 SF bug #460020: bug or feature: unicode() and subclasses.
Tim Peters <tim.peters@gmail.com>
parents: 19787
diff changeset
80 _PyLong_Copy(PyLongObject *src)
5158e4789459 SF bug #460020: bug or feature: unicode() and subclasses.
Tim Peters <tim.peters@gmail.com>
parents: 19787
diff changeset
81 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
82 PyLongObject *result;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
83 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
84
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
85 assert(src != NULL);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
86 i = src->ob_size;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
87 if (i < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
88 i = -(i);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
89 result = _PyLong_New(i);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
90 if (result != NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
91 result->ob_size = src->ob_size;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
92 while (--i >= 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
93 result->ob_digit[i] = src->ob_digit[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
94 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
95 return (PyObject *)result;
19837
5158e4789459 SF bug #460020: bug or feature: unicode() and subclasses.
Tim Peters <tim.peters@gmail.com>
parents: 19787
diff changeset
96 }
5158e4789459 SF bug #460020: bug or feature: unicode() and subclasses.
Tim Peters <tim.peters@gmail.com>
parents: 19787
diff changeset
97
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
98 /* Create a new long int object from a C long int */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
99
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
100 PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
101 PyLong_FromLong(long ival)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
102 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
103 PyLongObject *v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
104 unsigned long abs_ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
105 unsigned long t; /* unsigned so >> doesn't propagate sign bit */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
106 int ndigits = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
107 int negative = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
108
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
109 if (ival < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
110 /* if LONG_MIN == -LONG_MAX-1 (true on most platforms) then
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
111 ANSI C says that the result of -ival is undefined when ival
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
112 == LONG_MIN. Hence the following workaround. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
113 abs_ival = (unsigned long)(-1-ival) + 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
114 negative = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
115 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
116 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
117 abs_ival = (unsigned long)ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
118 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
119
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
120 /* Count the number of Python digits.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
121 We used to pick 5 ("big enough for anything"), but that's a
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
122 waste of time and space given that 5*15 = 75 bits are rarely
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
123 needed. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
124 t = abs_ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
125 while (t) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
126 ++ndigits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
127 t >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
128 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
129 v = _PyLong_New(ndigits);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
130 if (v != NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
131 digit *p = v->ob_digit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
132 v->ob_size = negative ? -ndigits : ndigits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
133 t = abs_ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
134 while (t) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
135 *p++ = (digit)(t & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
136 t >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
137 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
138 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
139 return (PyObject *)v;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
140 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
141
4870
68f4134869db Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents: 4587
diff changeset
142 /* Create a new long int object from a C unsigned long int */
68f4134869db Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents: 4587
diff changeset
143
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
144 PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
145 PyLong_FromUnsignedLong(unsigned long ival)
4870
68f4134869db Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents: 4587
diff changeset
146 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
147 PyLongObject *v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
148 unsigned long t;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
149 int ndigits = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
150
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
151 /* Count the number of Python digits. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
152 t = (unsigned long)ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
153 while (t) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
154 ++ndigits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
155 t >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
156 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
157 v = _PyLong_New(ndigits);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
158 if (v != NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
159 digit *p = v->ob_digit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
160 Py_SIZE(v) = ndigits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
161 while (ival) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
162 *p++ = (digit)(ival & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
163 ival >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
164 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
165 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
166 return (PyObject *)v;
4870
68f4134869db Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents: 4587
diff changeset
167 }
68f4134869db Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents: 4587
diff changeset
168
254
71b0bd5ed162 Added dnewlongobject(), function to convert double to long int.
Guido van Rossum <guido@python.org>
parents: 250
diff changeset
169 /* Create a new long int object from a C double */
71b0bd5ed162 Added dnewlongobject(), function to convert double to long int.
Guido van Rossum <guido@python.org>
parents: 250
diff changeset
170
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
171 PyObject *
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
172 PyLong_FromDouble(double dval)
254
71b0bd5ed162 Added dnewlongobject(), function to convert double to long int.
Guido van Rossum <guido@python.org>
parents: 250
diff changeset
173 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
174 PyLongObject *v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
175 double frac;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
176 int i, ndig, expo, neg;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
177 neg = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
178 if (Py_IS_INFINITY(dval)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
179 PyErr_SetString(PyExc_OverflowError,
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
180 "cannot convert float infinity to integer");
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
181 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
182 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
183 if (Py_IS_NAN(dval)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
184 PyErr_SetString(PyExc_ValueError,
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
185 "cannot convert float NaN to integer");
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
186 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
187 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
188 if (dval < 0.0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
189 neg = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
190 dval = -dval;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
191 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
192 frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
193 if (expo <= 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
194 return PyLong_FromLong(0L);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
195 ndig = (expo-1) / PyLong_SHIFT + 1; /* Number of 'digits' in result */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
196 v = _PyLong_New(ndig);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
197 if (v == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
198 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
199 frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
200 for (i = ndig; --i >= 0; ) {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
201 digit bits = (digit)frac;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
202 v->ob_digit[i] = bits;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
203 frac = frac - (double)bits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
204 frac = ldexp(frac, PyLong_SHIFT);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
205 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
206 if (neg)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
207 Py_SIZE(v) = -(Py_SIZE(v));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
208 return (PyObject *)v;
254
71b0bd5ed162 Added dnewlongobject(), function to convert double to long int.
Guido van Rossum <guido@python.org>
parents: 250
diff changeset
209 }
71b0bd5ed162 Added dnewlongobject(), function to convert double to long int.
Guido van Rossum <guido@python.org>
parents: 250
diff changeset
210
39995
6ba402b60041 Forward-port of r52136,52138: a review of overflow-detecting code.
Armin Rigo <arigo@tunes.org>
parents: 39463
diff changeset
211 /* Checking for overflow in PyLong_AsLong is a PITA since C doesn't define
6ba402b60041 Forward-port of r52136,52138: a review of overflow-detecting code.
Armin Rigo <arigo@tunes.org>
parents: 39463
diff changeset
212 * anything about what happens when a signed integer operation overflows,
6ba402b60041 Forward-port of r52136,52138: a review of overflow-detecting code.
Armin Rigo <arigo@tunes.org>
parents: 39463
diff changeset
213 * and some compilers think they're doing you a favor by being "clever"
6ba402b60041 Forward-port of r52136,52138: a review of overflow-detecting code.
Armin Rigo <arigo@tunes.org>
parents: 39463
diff changeset
214 * then. The bit pattern for the largest postive signed long is
6ba402b60041 Forward-port of r52136,52138: a review of overflow-detecting code.
Armin Rigo <arigo@tunes.org>
parents: 39463
diff changeset
215 * (unsigned long)LONG_MAX, and for the smallest negative signed long
6ba402b60041 Forward-port of r52136,52138: a review of overflow-detecting code.
Armin Rigo <arigo@tunes.org>
parents: 39463
diff changeset
216 * it is abs(LONG_MIN), which we could write -(unsigned long)LONG_MIN.
6ba402b60041 Forward-port of r52136,52138: a review of overflow-detecting code.
Armin Rigo <arigo@tunes.org>
parents: 39463
diff changeset
217 * However, some other compilers warn about applying unary minus to an
6ba402b60041 Forward-port of r52136,52138: a review of overflow-detecting code.
Armin Rigo <arigo@tunes.org>
parents: 39463
diff changeset
218 * unsigned operand. Hence the weird "0-".
6ba402b60041 Forward-port of r52136,52138: a review of overflow-detecting code.
Armin Rigo <arigo@tunes.org>
parents: 39463
diff changeset
219 */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
220 #define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
221 #define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN)
39995
6ba402b60041 Forward-port of r52136,52138: a review of overflow-detecting code.
Armin Rigo <arigo@tunes.org>
parents: 39463
diff changeset
222
57851
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
223 /* Get a C long int from a Python long or Python int object.
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
224 On overflow, returns -1 and sets *overflow to 1 or -1 depending
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
225 on the sign of the result. Otherwise *overflow is 0.
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
226
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
227 For other errors (e.g., type error), returns -1 and sets an error
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
228 condition.
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
229 */
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
231 long
57851
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
232 PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
233 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
234 /* This version by Tim Peters */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
235 register PyLongObject *v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
236 unsigned long x, prev;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
237 long res;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
238 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
239 int sign;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
240 int do_decref = 0; /* if nb_int was called */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
241
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
242 *overflow = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
243 if (vv == NULL) {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
244 PyErr_BadInternalCall();
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
245 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
246 }
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
247
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
248 if(PyInt_Check(vv))
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
249 return PyInt_AsLong(vv);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
250
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
251 if (!PyLong_Check(vv)) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
252 PyNumberMethods *nb;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
253 nb = vv->ob_type->tp_as_number;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
254 if (nb == NULL || nb->nb_int == NULL) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
255 PyErr_SetString(PyExc_TypeError,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
256 "an integer is required");
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
257 return -1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
258 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
259 vv = (*nb->nb_int) (vv);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
260 if (vv == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
261 return -1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
262 do_decref = 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
263 if(PyInt_Check(vv)) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
264 res = PyInt_AsLong(vv);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
265 goto exit;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
266 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
267 if (!PyLong_Check(vv)) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
268 Py_DECREF(vv);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
269 PyErr_SetString(PyExc_TypeError,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
270 "nb_int should return int object");
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
271 return -1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
272 }
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
273 }
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
274
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
275 res = -1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
276 v = (PyLongObject *)vv;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
277 i = Py_SIZE(v);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
278
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
279 switch (i) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
280 case -1:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
281 res = -(sdigit)v->ob_digit[0];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
282 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
283 case 0:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
284 res = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
285 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
286 case 1:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
287 res = v->ob_digit[0];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
288 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
289 default:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
290 sign = 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
291 x = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
292 if (i < 0) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
293 sign = -1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
294 i = -(i);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
295 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
296 while (--i >= 0) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
297 prev = x;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
298 x = (x << PyLong_SHIFT) + v->ob_digit[i];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
299 if ((x >> PyLong_SHIFT) != prev) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
300 *overflow = sign;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
301 goto exit;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
302 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
303 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
304 /* Haven't lost any bits, but casting to long requires extra
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
305 * care (see comment above).
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
306 */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
307 if (x <= (unsigned long)LONG_MAX) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
308 res = (long)x * sign;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
309 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
310 else if (sign < 0 && x == PY_ABS_LONG_MIN) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
311 res = LONG_MIN;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
312 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
313 else {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
314 *overflow = sign;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
315 /* res is already set to -1 */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
316 }
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
317 }
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
318 exit:
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
319 if (do_decref) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
320 Py_DECREF(vv);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
321 }
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
322 return res;
57851
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
323 }
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
324
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
325 /* Get a C long int from a long int object.
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
326 Returns -1 and sets an error condition if overflow occurs. */
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
327
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
328 long
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
329 PyLong_AsLong(PyObject *obj)
28de83f17d08 Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk.
Mark Dickinson <dickinsm@gmail.com>
parents: 56733
diff changeset
330 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
331 int overflow;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
332 long result = PyLong_AsLongAndOverflow(obj, &overflow);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
333 if (overflow) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
334 /* XXX: could be cute and give a different
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
335 message for overflow == -1 */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
336 PyErr_SetString(PyExc_OverflowError,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
337 "Python int too large to convert to C long");
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
338 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
339 return result;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
340 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
341
39463
6cafdc81cfde Patch #1538606, Patch to fix __index__() clipping.
Neal Norwitz <nnorwitz@gmail.com>
parents: 39141
diff changeset
342 /* Get a Py_ssize_t from a long int object.
6cafdc81cfde Patch #1538606, Patch to fix __index__() clipping.
Neal Norwitz <nnorwitz@gmail.com>
parents: 39141
diff changeset
343 Returns -1 and sets an error condition if overflow occurs. */
6cafdc81cfde Patch #1538606, Patch to fix __index__() clipping.
Neal Norwitz <nnorwitz@gmail.com>
parents: 39141
diff changeset
344
6cafdc81cfde Patch #1538606, Patch to fix __index__() clipping.
Neal Norwitz <nnorwitz@gmail.com>
parents: 39141
diff changeset
345 Py_ssize_t
44945
bbc719a8b58b Backport of several functions from Python 3.0 to 2.6 including PyUnicode_FromString, PyUnicode_Format and PyLong_From/AsSsize_t. The functions are partly required for the backport of the bytearray type and _fileio module. They should also make it easier to port C to 3.0.
Christian Heimes <christian@cheimes.de>
parents: 44749
diff changeset
346 PyLong_AsSsize_t(PyObject *vv) {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
347 register PyLongObject *v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
348 size_t x, prev;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
349 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
350 int sign;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
351
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
352 if (vv == NULL || !PyLong_Check(vv)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
353 PyErr_BadInternalCall();
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
354 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
355 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
356 v = (PyLongObject *)vv;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
357 i = v->ob_size;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
358 sign = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
359 x = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
360 if (i < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
361 sign = -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
362 i = -(i);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
363 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
364 while (--i >= 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
365 prev = x;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
366 x = (x << PyLong_SHIFT) | v->ob_digit[i];
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
367 if ((x >> PyLong_SHIFT) != prev)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
368 goto overflow;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
369 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
370 /* Haven't lost any bits, but casting to a signed type requires
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
371 * extra care (see comment above).
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
372 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
373 if (x <= (size_t)PY_SSIZE_T_MAX) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
374 return (Py_ssize_t)x * sign;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
375 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
376 else if (sign < 0 && x == PY_ABS_SSIZE_T_MIN) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
377 return PY_SSIZE_T_MIN;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
378 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
379 /* else overflow */
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
380
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
381 overflow:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
382 PyErr_SetString(PyExc_OverflowError,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
383 "long int too large to convert to int");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
384 return -1;
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
385 }
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
386
24777
696a284569e6 Fix comment for PyLong_AsUnsignedLong() to say that the return value
Guido van Rossum <guido@python.org>
parents: 24775
diff changeset
387 /* Get a C unsigned long int from a long int object.
4870
68f4134869db Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents: 4587
diff changeset
388 Returns -1 and sets an error condition if overflow occurs. */
68f4134869db Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents: 4587
diff changeset
389
68f4134869db Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents: 4587
diff changeset
390 unsigned long
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
391 PyLong_AsUnsignedLong(PyObject *vv)
4870
68f4134869db Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents: 4587
diff changeset
392 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
393 register PyLongObject *v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
394 unsigned long x, prev;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
395 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
396
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
397 if (vv == NULL || !PyLong_Check(vv)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
398 if (vv != NULL && PyInt_Check(vv)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
399 long val = PyInt_AsLong(vv);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
400 if (val < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
401 PyErr_SetString(PyExc_OverflowError,
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
402 "can't convert negative value "
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
403 "to unsigned long");
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
404 return (unsigned long) -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
405 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
406 return val;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
407 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
408 PyErr_BadInternalCall();
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
409 return (unsigned long) -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
410 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
411 v = (PyLongObject *)vv;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
412 i = Py_SIZE(v);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
413 x = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
414 if (i < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
415 PyErr_SetString(PyExc_OverflowError,
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
416 "can't convert negative value to unsigned long");
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
417 return (unsigned long) -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
418 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
419 while (--i >= 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
420 prev = x;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
421 x = (x << PyLong_SHIFT) | v->ob_digit[i];
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
422 if ((x >> PyLong_SHIFT) != prev) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
423 PyErr_SetString(PyExc_OverflowError,
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
424 "long int too large to convert");
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
425 return (unsigned long) -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
426 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
427 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
428 return x;
4870
68f4134869db Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents: 4587
diff changeset
429 }
68f4134869db Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents: 4587
diff changeset
430
28652
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
431 /* Get a C unsigned long int from a long int object, ignoring the high bits.
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
432 Returns -1 and sets an error condition if an error occurs. */
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
433
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
434 unsigned long
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
435 PyLong_AsUnsignedLongMask(PyObject *vv)
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
436 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
437 register PyLongObject *v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
438 unsigned long x;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
439 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
440 int sign;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
441
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
442 if (vv == NULL || !PyLong_Check(vv)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
443 if (vv != NULL && PyInt_Check(vv))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
444 return PyInt_AsUnsignedLongMask(vv);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
445 PyErr_BadInternalCall();
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
446 return (unsigned long) -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
447 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
448 v = (PyLongObject *)vv;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
449 i = v->ob_size;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
450 sign = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
451 x = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
452 if (i < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
453 sign = -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
454 i = -i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
455 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
456 while (--i >= 0) {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
457 x = (x << PyLong_SHIFT) | v->ob_digit[i];
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
458 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
459 return x * sign;
28652
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
460 }
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
461
27549
7fcdeeb16ec0 _PyLong_NumBits(): The definition of this was too specific to the quirky
Tim Peters <tim.peters@gmail.com>
parents: 27521
diff changeset
462 int
7fcdeeb16ec0 _PyLong_NumBits(): The definition of this was too specific to the quirky
Tim Peters <tim.peters@gmail.com>
parents: 27521
diff changeset
463 _PyLong_Sign(PyObject *vv)
7fcdeeb16ec0 _PyLong_NumBits(): The definition of this was too specific to the quirky
Tim Peters <tim.peters@gmail.com>
parents: 27521
diff changeset
464 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
465 PyLongObject *v = (PyLongObject *)vv;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
466
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
467 assert(v != NULL);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
468 assert(PyLong_Check(v));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
469
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
470 return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1);
27549
7fcdeeb16ec0 _PyLong_NumBits(): The definition of this was too specific to the quirky
Tim Peters <tim.peters@gmail.com>
parents: 27521
diff changeset
471 }
7fcdeeb16ec0 _PyLong_NumBits(): The definition of this was too specific to the quirky
Tim Peters <tim.peters@gmail.com>
parents: 27521
diff changeset
472
27487
0904d878b8f1 Added new private API function _PyLong_NumBits. This will be used at the
Tim Peters <tim.peters@gmail.com>
parents: 26867
diff changeset
473 size_t
0904d878b8f1 Added new private API function _PyLong_NumBits. This will be used at the
Tim Peters <tim.peters@gmail.com>
parents: 26867
diff changeset
474 _PyLong_NumBits(PyObject *vv)
0904d878b8f1 Added new private API function _PyLong_NumBits. This will be used at the
Tim Peters <tim.peters@gmail.com>
parents: 26867
diff changeset
475 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
476 PyLongObject *v = (PyLongObject *)vv;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
477 size_t result = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
478 Py_ssize_t ndigits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
479
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
480 assert(v != NULL);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
481 assert(PyLong_Check(v));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
482 ndigits = ABS(Py_SIZE(v));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
483 assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
484 if (ndigits > 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
485 digit msd = v->ob_digit[ndigits - 1];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
486
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
487 result = (ndigits - 1) * PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
488 if (result / PyLong_SHIFT != (size_t)(ndigits - 1))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
489 goto Overflow;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
490 do {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
491 ++result;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
492 if (result == 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
493 goto Overflow;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
494 msd >>= 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
495 } while (msd);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
496 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
497 return result;
27487
0904d878b8f1 Added new private API function _PyLong_NumBits. This will be used at the
Tim Peters <tim.peters@gmail.com>
parents: 26867
diff changeset
498
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
499 Overflow:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
500 PyErr_SetString(PyExc_OverflowError, "long has too many bits "
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
501 "to express in a platform size_t");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
502 return (size_t)-1;
27487
0904d878b8f1 Added new private API function _PyLong_NumBits. This will be used at the
Tim Peters <tim.peters@gmail.com>
parents: 26867
diff changeset
503 }
0904d878b8f1 Added new private API function _PyLong_NumBits. This will be used at the
Tim Peters <tim.peters@gmail.com>
parents: 26867
diff changeset
504
18082
dd09f11fa40d Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents: 15946
diff changeset
505 PyObject *
dd09f11fa40d Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents: 15946
diff changeset
506 _PyLong_FromByteArray(const unsigned char* bytes, size_t n,
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
507 int little_endian, int is_signed)
18082
dd09f11fa40d Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents: 15946
diff changeset
508 {
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
509 const unsigned char* pstartbyte; /* LSB of bytes */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
510 int incr; /* direction to move pstartbyte */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
511 const unsigned char* pendbyte; /* MSB of bytes */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
512 size_t numsignificantbytes; /* number of bytes that matter */
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
513 Py_ssize_t ndigits; /* number of Python long digits */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
514 PyLongObject* v; /* result */
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
515 Py_ssize_t idigit = 0; /* next free index in v->ob_digit */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
516
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
517 if (n == 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
518 return PyLong_FromLong(0L);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
519
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
520 if (little_endian) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
521 pstartbyte = bytes;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
522 pendbyte = bytes + n - 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
523 incr = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
524 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
525 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
526 pstartbyte = bytes + n - 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
527 pendbyte = bytes;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
528 incr = -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
529 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
530
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
531 if (is_signed)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
532 is_signed = *pendbyte >= 0x80;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
533
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
534 /* Compute numsignificantbytes. This consists of finding the most
68588
cd8d3c2d3bce #11565: Fix several typos. Patch by Piotr Kasprzyk.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 68503
diff changeset
535 significant byte. Leading 0 bytes are insignificant if the number
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
536 is positive, and leading 0xff bytes if negative. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
537 {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
538 size_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
539 const unsigned char* p = pendbyte;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
540 const int pincr = -incr; /* search MSB to LSB */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
541 const unsigned char insignficant = is_signed ? 0xff : 0x00;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
542
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
543 for (i = 0; i < n; ++i, p += pincr) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
544 if (*p != insignficant)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
545 break;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
546 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
547 numsignificantbytes = n - i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
548 /* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
549 actually has 2 significant bytes. OTOH, 0xff0001 ==
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
550 -0x00ffff, so we wouldn't *need* to bump it there; but we
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
551 do for 0xffff = -0x0001. To be safe without bothering to
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
552 check every case, bump it regardless. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
553 if (is_signed && numsignificantbytes < n)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
554 ++numsignificantbytes;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
555 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
556
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
557 /* How many Python long digits do we need? We have
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
558 8*numsignificantbytes bits, and each Python long digit has
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
559 PyLong_SHIFT bits, so it's the ceiling of the quotient. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
560 /* catch overflow before it happens */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
561 if (numsignificantbytes > (PY_SSIZE_T_MAX - PyLong_SHIFT) / 8) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
562 PyErr_SetString(PyExc_OverflowError,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
563 "byte array too long to convert to int");
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
564 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
565 }
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
566 ndigits = (numsignificantbytes * 8 + PyLong_SHIFT - 1) / PyLong_SHIFT;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
567 v = _PyLong_New(ndigits);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
568 if (v == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
569 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
570
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
571 /* Copy the bits over. The tricky parts are computing 2's-comp on
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
572 the fly for signed numbers, and dealing with the mismatch between
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
573 8-bit bytes and (probably) 15-bit Python digits.*/
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
574 {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
575 size_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
576 twodigits carry = 1; /* for 2's-comp calculation */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
577 twodigits accum = 0; /* sliding register */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
578 unsigned int accumbits = 0; /* number of bits in accum */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
579 const unsigned char* p = pstartbyte;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
580
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
581 for (i = 0; i < numsignificantbytes; ++i, p += incr) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
582 twodigits thisbyte = *p;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
583 /* Compute correction for 2's comp, if needed. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
584 if (is_signed) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
585 thisbyte = (0xff ^ thisbyte) + carry;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
586 carry = thisbyte >> 8;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
587 thisbyte &= 0xff;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
588 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
589 /* Because we're going LSB to MSB, thisbyte is
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
590 more significant than what's already in accum,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
591 so needs to be prepended to accum. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
592 accum |= (twodigits)thisbyte << accumbits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
593 accumbits += 8;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
594 if (accumbits >= PyLong_SHIFT) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
595 /* There's enough to fill a Python digit. */
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
596 assert(idigit < ndigits);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
597 v->ob_digit[idigit] = (digit)(accum & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
598 ++idigit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
599 accum >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
600 accumbits -= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
601 assert(accumbits < PyLong_SHIFT);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
602 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
603 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
604 assert(accumbits < PyLong_SHIFT);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
605 if (accumbits) {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
606 assert(idigit < ndigits);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
607 v->ob_digit[idigit] = (digit)accum;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
608 ++idigit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
609 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
610 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
611
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
612 Py_SIZE(v) = is_signed ? -idigit : idigit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
613 return (PyObject *)long_normalize(v);
18082
dd09f11fa40d Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents: 15946
diff changeset
614 }
dd09f11fa40d Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents: 15946
diff changeset
615
dd09f11fa40d Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents: 15946
diff changeset
616 int
dd09f11fa40d Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents: 15946
diff changeset
617 _PyLong_AsByteArray(PyLongObject* v,
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
618 unsigned char* bytes, size_t n,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
619 int little_endian, int is_signed)
18082
dd09f11fa40d Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents: 15946
diff changeset
620 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
621 Py_ssize_t i; /* index into v->ob_digit */
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
622 Py_ssize_t ndigits; /* |v->ob_size| */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
623 twodigits accum; /* sliding register */
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
624 unsigned int accumbits; /* # bits in accum */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
625 int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
626 digit carry; /* for computing 2's-comp */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
627 size_t j; /* # bytes filled */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
628 unsigned char* p; /* pointer to next byte in bytes */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
629 int pincr; /* direction to move p */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
630
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
631 assert(v != NULL && PyLong_Check(v));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
632
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
633 if (Py_SIZE(v) < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
634 ndigits = -(Py_SIZE(v));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
635 if (!is_signed) {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
636 PyErr_SetString(PyExc_OverflowError,
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
637 "can't convert negative long to unsigned");
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
638 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
639 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
640 do_twos_comp = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
641 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
642 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
643 ndigits = Py_SIZE(v);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
644 do_twos_comp = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
645 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
646
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
647 if (little_endian) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
648 p = bytes;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
649 pincr = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
650 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
651 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
652 p = bytes + n - 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
653 pincr = -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
654 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
655
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
656 /* Copy over all the Python digits.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
657 It's crucial that every Python digit except for the MSD contribute
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
658 exactly PyLong_SHIFT bits to the total, so first assert that the long is
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
659 normalized. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
660 assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
661 j = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
662 accum = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
663 accumbits = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
664 carry = do_twos_comp ? 1 : 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
665 for (i = 0; i < ndigits; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
666 digit thisdigit = v->ob_digit[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
667 if (do_twos_comp) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
668 thisdigit = (thisdigit ^ PyLong_MASK) + carry;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
669 carry = thisdigit >> PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
670 thisdigit &= PyLong_MASK;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
671 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
672 /* Because we're going LSB to MSB, thisdigit is more
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
673 significant than what's already in accum, so needs to be
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
674 prepended to accum. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
675 accum |= (twodigits)thisdigit << accumbits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
676
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
677 /* The most-significant digit may be (probably is) at least
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
678 partly empty. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
679 if (i == ndigits - 1) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
680 /* Count # of sign bits -- they needn't be stored,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
681 * although for signed conversion we need later to
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
682 * make sure at least one sign bit gets stored. */
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
683 digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : thisdigit;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
684 while (s != 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
685 s >>= 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
686 accumbits++;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
687 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
688 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
689 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
690 accumbits += PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
691
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
692 /* Store as many bytes as possible. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
693 while (accumbits >= 8) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
694 if (j >= n)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
695 goto Overflow;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
696 ++j;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
697 *p = (unsigned char)(accum & 0xff);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
698 p += pincr;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
699 accumbits -= 8;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
700 accum >>= 8;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
701 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
702 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
703
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
704 /* Store the straggler (if any). */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
705 assert(accumbits < 8);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
706 assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
707 if (accumbits > 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
708 if (j >= n)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
709 goto Overflow;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
710 ++j;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
711 if (do_twos_comp) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
712 /* Fill leading bits of the byte with sign bits
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
713 (appropriately pretending that the long had an
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
714 infinite supply of sign bits). */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
715 accum |= (~(twodigits)0) << accumbits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
716 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
717 *p = (unsigned char)(accum & 0xff);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
718 p += pincr;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
719 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
720 else if (j == n && n > 0 && is_signed) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
721 /* The main loop filled the byte array exactly, so the code
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
722 just above didn't get to ensure there's a sign bit, and the
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
723 loop below wouldn't add one either. Make sure a sign bit
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
724 exists. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
725 unsigned char msb = *(p - pincr);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
726 int sign_bit_set = msb >= 0x80;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
727 assert(accumbits == 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
728 if (sign_bit_set == do_twos_comp)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
729 return 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
730 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
731 goto Overflow;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
732 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
733
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
734 /* Fill remaining bytes with copies of the sign bit. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
735 {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
736 unsigned char signbyte = do_twos_comp ? 0xffU : 0U;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
737 for ( ; j < n; ++j, p += pincr)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
738 *p = signbyte;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
739 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
740
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
741 return 0;
18082
dd09f11fa40d Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents: 15946
diff changeset
742
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
743 Overflow:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
744 PyErr_SetString(PyExc_OverflowError, "long too big to convert");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
745 return -1;
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
746
18082
dd09f11fa40d Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents: 15946
diff changeset
747 }
dd09f11fa40d Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents: 15946
diff changeset
748
9123
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
749 /* Create a new long (or int) object from a C pointer */
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
750
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
751 PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
752 PyLong_FromVoidPtr(void *p)
9123
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
753 {
18134
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
754 #if SIZEOF_VOID_P <= SIZEOF_LONG
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
755 if ((long)p < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
756 return PyLong_FromUnsignedLong((unsigned long)p);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
757 return PyInt_FromLong((long)p);
9123
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
758 #else
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
759
18134
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
760 #ifndef HAVE_LONG_LONG
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
761 # error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long"
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
762 #endif
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
763 #if SIZEOF_LONG_LONG < SIZEOF_VOID_P
28437
871da703e4c0 Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents: 28032
diff changeset
764 # error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
18134
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
765 #endif
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
766 /* optimize null pointers */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
767 if (p == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
768 return PyInt_FromLong(0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
769 return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)p);
18134
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
770
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
771 #endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
9123
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
772 }
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
773
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
774 /* Get a C pointer from a long object (or an int object in some cases) */
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
775
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
776 void *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
777 PyLong_AsVoidPtr(PyObject *vv)
9123
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
778 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
779 /* This function will allow int or long objects. If vv is neither,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
780 then the PyLong_AsLong*() functions will raise the exception:
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
781 PyExc_SystemError, "bad argument to internal function"
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
782 */
18134
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
783 #if SIZEOF_VOID_P <= SIZEOF_LONG
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
784 long x;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
785
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
786 if (PyInt_Check(vv))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
787 x = PyInt_AS_LONG(vv);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
788 else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
789 x = PyLong_AsLong(vv);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
790 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
791 x = PyLong_AsUnsignedLong(vv);
9123
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
792 #else
18134
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
793
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
794 #ifndef HAVE_LONG_LONG
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
795 # error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
796 #endif
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
797 #if SIZEOF_LONG_LONG < SIZEOF_VOID_P
28437
871da703e4c0 Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents: 28032
diff changeset
798 # error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
18134
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
799 #endif
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
800 PY_LONG_LONG x;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
801
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
802 if (PyInt_Check(vv))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
803 x = PyInt_AS_LONG(vv);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
804 else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
805 x = PyLong_AsLongLong(vv);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
806 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
807 x = PyLong_AsUnsignedLongLong(vv);
18134
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
808
eff8da7c3dcb PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents: 18121
diff changeset
809 #endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
9123
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
810
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
811 if (x == -1 && PyErr_Occurred())
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
812 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
813 return (void *)x;
9123
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
814 }
17d0c51e0887 Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents: 9094
diff changeset
815
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
816 #ifdef HAVE_LONG_LONG
18093
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
817
28437
871da703e4c0 Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents: 28032
diff changeset
818 /* Initial PY_LONG_LONG support by Chris Herborth (chrish@qnx.com), later
18093
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
819 * rewritten to use the newer PyLong_{As,From}ByteArray API.
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
820 */
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
821
18121
166b7b365851 Change IS_LITTLE_ENDIAN macro -- a little faster now.
Tim Peters <tim.peters@gmail.com>
parents: 18115
diff changeset
822 #define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
823 #define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN)
18093
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
824
28437
871da703e4c0 Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents: 28032
diff changeset
825 /* Create a new long int object from a C PY_LONG_LONG int. */
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
826
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
827 PyObject *
28437
871da703e4c0 Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents: 28032
diff changeset
828 PyLong_FromLongLong(PY_LONG_LONG ival)
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
829 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
830 PyLongObject *v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
831 unsigned PY_LONG_LONG abs_ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
832 unsigned PY_LONG_LONG t; /* unsigned so >> doesn't propagate sign bit */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
833 int ndigits = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
834 int negative = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
835
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
836 if (ival < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
837 /* avoid signed overflow on negation; see comments
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
838 in PyLong_FromLong above. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
839 abs_ival = (unsigned PY_LONG_LONG)(-1-ival) + 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
840 negative = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
841 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
842 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
843 abs_ival = (unsigned PY_LONG_LONG)ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
844 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
845
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
846 /* Count the number of Python digits.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
847 We used to pick 5 ("big enough for anything"), but that's a
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
848 waste of time and space given that 5*15 = 75 bits are rarely
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
849 needed. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
850 t = abs_ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
851 while (t) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
852 ++ndigits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
853 t >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
854 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
855 v = _PyLong_New(ndigits);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
856 if (v != NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
857 digit *p = v->ob_digit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
858 Py_SIZE(v) = negative ? -ndigits : ndigits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
859 t = abs_ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
860 while (t) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
861 *p++ = (digit)(t & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
862 t >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
863 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
864 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
865 return (PyObject *)v;
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
866 }
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
867
28437
871da703e4c0 Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents: 28032
diff changeset
868 /* Create a new long int object from a C unsigned PY_LONG_LONG int. */
18093
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
869
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
870 PyObject *
28437
871da703e4c0 Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents: 28032
diff changeset
871 PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival)
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
872 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
873 PyLongObject *v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
874 unsigned PY_LONG_LONG t;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
875 int ndigits = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
876
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
877 /* Count the number of Python digits. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
878 t = (unsigned PY_LONG_LONG)ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
879 while (t) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
880 ++ndigits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
881 t >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
882 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
883 v = _PyLong_New(ndigits);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
884 if (v != NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
885 digit *p = v->ob_digit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
886 Py_SIZE(v) = ndigits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
887 while (ival) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
888 *p++ = (digit)(ival & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
889 ival >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
890 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
891 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
892 return (PyObject *)v;
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
893 }
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
894
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
895 /* Create a new long int object from a C Py_ssize_t. */
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
896
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
897 PyObject *
44945
bbc719a8b58b Backport of several functions from Python 3.0 to 2.6 including PyUnicode_FromString, PyUnicode_Format and PyLong_From/AsSsize_t. The functions are partly required for the backport of the bytearray type and _fileio module. They should also make it easier to port C to 3.0.
Christian Heimes <christian@cheimes.de>
parents: 44749
diff changeset
898 PyLong_FromSsize_t(Py_ssize_t ival)
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
899 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
900 Py_ssize_t bytes = ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
901 int one = 1;
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
902 return _PyLong_FromByteArray((unsigned char *)&bytes,
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
903 SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 1);
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
904 }
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
905
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
906 /* Create a new long int object from a C size_t. */
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
907
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
908 PyObject *
44945
bbc719a8b58b Backport of several functions from Python 3.0 to 2.6 including PyUnicode_FromString, PyUnicode_Format and PyLong_From/AsSsize_t. The functions are partly required for the backport of the bytearray type and _fileio module. They should also make it easier to port C to 3.0.
Christian Heimes <christian@cheimes.de>
parents: 44749
diff changeset
909 PyLong_FromSize_t(size_t ival)
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
910 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
911 size_t bytes = ival;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
912 int one = 1;
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
913 return _PyLong_FromByteArray((unsigned char *)&bytes,
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
914 SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0);
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
915 }
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
916
28437
871da703e4c0 Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents: 28032
diff changeset
917 /* Get a C PY_LONG_LONG int from a long int object.
18093
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
918 Return -1 and set an error if overflow occurs. */
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
919
28437
871da703e4c0 Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents: 28032
diff changeset
920 PY_LONG_LONG
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
921 PyLong_AsLongLong(PyObject *vv)
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
922 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
923 PY_LONG_LONG bytes;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
924 int one = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
925 int res;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
926
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
927 if (vv == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
928 PyErr_BadInternalCall();
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
929 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
930 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
931 if (!PyLong_Check(vv)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
932 PyNumberMethods *nb;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
933 PyObject *io;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
934 if (PyInt_Check(vv))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
935 return (PY_LONG_LONG)PyInt_AsLong(vv);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
936 if ((nb = vv->ob_type->tp_as_number) == NULL ||
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
937 nb->nb_int == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
938 PyErr_SetString(PyExc_TypeError, "an integer is required");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
939 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
940 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
941 io = (*nb->nb_int) (vv);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
942 if (io == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
943 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
944 if (PyInt_Check(io)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
945 bytes = PyInt_AsLong(io);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
946 Py_DECREF(io);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
947 return bytes;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
948 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
949 if (PyLong_Check(io)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
950 bytes = PyLong_AsLongLong(io);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
951 Py_DECREF(io);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
952 return bytes;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
953 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
954 Py_DECREF(io);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
955 PyErr_SetString(PyExc_TypeError, "integer conversion failed");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
956 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
957 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
958
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
959 res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
960 SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
961
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
962 /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
963 if (res < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
964 return (PY_LONG_LONG)-1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
965 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
966 return bytes;
18093
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
967 }
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
968
28437
871da703e4c0 Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents: 28032
diff changeset
969 /* Get a C unsigned PY_LONG_LONG int from a long int object.
18093
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
970 Return -1 and set an error if overflow occurs. */
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
971
28437
871da703e4c0 Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents: 28032
diff changeset
972 unsigned PY_LONG_LONG
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
973 PyLong_AsUnsignedLongLong(PyObject *vv)
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
974 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
975 unsigned PY_LONG_LONG bytes;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
976 int one = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
977 int res;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
978
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
979 if (vv == NULL || !PyLong_Check(vv)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
980 PyErr_BadInternalCall();
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
981 return (unsigned PY_LONG_LONG)-1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
982 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
983
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
984 res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
985 SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
986
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
987 /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
988 if (res < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
989 return (unsigned PY_LONG_LONG)res;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
990 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
991 return bytes;
18093
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
992 }
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
993
28652
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
994 /* Get a C unsigned long int from a long int object, ignoring the high bits.
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
995 Returns -1 and sets an error condition if an error occurs. */
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
996
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
997 unsigned PY_LONG_LONG
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
998 PyLong_AsUnsignedLongLongMask(PyObject *vv)
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
999 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1000 register PyLongObject *v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1001 unsigned PY_LONG_LONG x;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1002 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1003 int sign;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1004
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1005 if (vv == NULL || !PyLong_Check(vv)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1006 PyErr_BadInternalCall();
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1007 return (unsigned long) -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1008 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1009 v = (PyLongObject *)vv;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1010 i = v->ob_size;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1011 sign = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1012 x = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1013 if (i < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1014 sign = -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1015 i = -i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1016 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1017 while (--i >= 0) {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1018 x = (x << PyLong_SHIFT) | v->ob_digit[i];
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1019 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1020 return x * sign;
28652
28a2975514cd SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents: 28437
diff changeset
1021 }
58581
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1022
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1023 /* Get a C long long int from a Python long or Python int object.
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1024 On overflow, returns -1 and sets *overflow to 1 or -1 depending
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1025 on the sign of the result. Otherwise *overflow is 0.
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1026
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1027 For other errors (e.g., type error), returns -1 and sets an error
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1028 condition.
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1029 */
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1030
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1031 PY_LONG_LONG
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1032 PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1033 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1034 /* This version by Tim Peters */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1035 register PyLongObject *v;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1036 unsigned PY_LONG_LONG x, prev;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1037 PY_LONG_LONG res;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1038 Py_ssize_t i;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1039 int sign;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1040 int do_decref = 0; /* if nb_int was called */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1041
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1042 *overflow = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1043 if (vv == NULL) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1044 PyErr_BadInternalCall();
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1045 return -1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1046 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1047
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1048 if (PyInt_Check(vv))
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1049 return PyInt_AsLong(vv);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1050
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1051 if (!PyLong_Check(vv)) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1052 PyNumberMethods *nb;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1053 nb = vv->ob_type->tp_as_number;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1054 if (nb == NULL || nb->nb_int == NULL) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1055 PyErr_SetString(PyExc_TypeError,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1056 "an integer is required");
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1057 return -1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1058 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1059 vv = (*nb->nb_int) (vv);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1060 if (vv == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1061 return -1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1062 do_decref = 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1063 if(PyInt_Check(vv)) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1064 res = PyInt_AsLong(vv);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1065 goto exit;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1066 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1067 if (!PyLong_Check(vv)) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1068 Py_DECREF(vv);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1069 PyErr_SetString(PyExc_TypeError,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1070 "nb_int should return int object");
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1071 return -1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1072 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1073 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1074
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1075 res = -1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1076 v = (PyLongObject *)vv;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1077 i = Py_SIZE(v);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1078
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1079 switch (i) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1080 case -1:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1081 res = -(sdigit)v->ob_digit[0];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1082 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1083 case 0:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1084 res = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1085 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1086 case 1:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1087 res = v->ob_digit[0];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1088 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1089 default:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1090 sign = 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1091 x = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1092 if (i < 0) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1093 sign = -1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1094 i = -(i);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1095 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1096 while (--i >= 0) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1097 prev = x;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1098 x = (x << PyLong_SHIFT) + v->ob_digit[i];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1099 if ((x >> PyLong_SHIFT) != prev) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1100 *overflow = sign;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1101 goto exit;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1102 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1103 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1104 /* Haven't lost any bits, but casting to long requires extra
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1105 * care (see comment above).
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1106 */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1107 if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1108 res = (PY_LONG_LONG)x * sign;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1109 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1110 else if (sign < 0 && x == PY_ABS_LLONG_MIN) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1111 res = PY_LLONG_MIN;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1112 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1113 else {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1114 *overflow = sign;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1115 /* res is already set to -1 */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1116 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1117 }
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1118 exit:
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1119 if (do_decref) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1120 Py_DECREF(vv);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1121 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1122 return res;
58581
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1123 }
6295e16303a7 Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
Mark Dickinson <dickinsm@gmail.com>
parents: 58085
diff changeset
1124
18093
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
1125 #undef IS_LITTLE_ENDIAN
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
1126
8822
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
1127 #endif /* HAVE_LONG_LONG */
bd47ee068b83 Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents: 8808
diff changeset
1128
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
1129
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
1130 static int
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
1131 convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1132 if (PyLong_Check(v)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1133 *a = (PyLongObject *) v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1134 Py_INCREF(v);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1135 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1136 else if (PyInt_Check(v)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1137 *a = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(v));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1138 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1139 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1140 return 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1141 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1142 if (PyLong_Check(w)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1143 *b = (PyLongObject *) w;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1144 Py_INCREF(w);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1145 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1146 else if (PyInt_Check(w)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1147 *b = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(w));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1148 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1149 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1150 Py_DECREF(*a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1151 return 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1152 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1153 return 1;
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
1154 }
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
1155
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
1156 #define CONVERT_BINOP(v, w, a, b) \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
1157 do { \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
1158 if (!convert_binop(v, w, a, b)) { \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
1159 Py_INCREF(Py_NotImplemented); \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
1160 return Py_NotImplemented; \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
1161 } \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
1162 } while(0) \
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
1163
52284
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1164 /* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d <
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1165 2**k if d is nonzero, else 0. */
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1166
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1167 static const unsigned char BitLengthTable[32] = {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1168 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1169 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
52284
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1170 };
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1171
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1172 static int
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1173 bits_in_digit(digit d)
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1174 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1175 int d_bits = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1176 while (d >= 32) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1177 d_bits += 6;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1178 d >>= 6;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1179 }
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1180 d_bits += (int)BitLengthTable[d];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1181 return d_bits;
52284
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1182 }
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
1183
24750
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1184 /* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n]
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1185 * is modified in place, by adding y to it. Carries are propagated as far as
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1186 * x[m-1], and the remaining carry (0 or 1) is returned.
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1187 */
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1188 static digit
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
1189 v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
24750
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1190 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1191 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1192 digit carry = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1193
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1194 assert(m >= n);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1195 for (i = 0; i < n; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1196 carry += x[i] + y[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1197 x[i] = carry & PyLong_MASK;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1198 carry >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1199 assert((carry & 1) == carry);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1200 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1201 for (; carry && i < m; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1202 carry += x[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1203 x[i] = carry & PyLong_MASK;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1204 carry >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1205 assert((carry & 1) == carry);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1206 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1207 return carry;
24750
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1208 }
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1209
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1210 /* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n]
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1211 * is modified in place, by subtracting y from it. Borrows are propagated as
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1212 * far as x[m-1], and the remaining borrow (0 or 1) is returned.
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1213 */
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1214 static digit
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
1215 v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
24750
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1216 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1217 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1218 digit borrow = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1219
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1220 assert(m >= n);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1221 for (i = 0; i < n; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1222 borrow = x[i] - y[i] - borrow;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1223 x[i] = borrow & PyLong_MASK;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1224 borrow >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1225 borrow &= 1; /* keep only 1 sign bit */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1226 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1227 for (; borrow && i < m; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1228 borrow = x[i] - borrow;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1229 x[i] = borrow & PyLong_MASK;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1230 borrow >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1231 borrow &= 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1232 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1233 return borrow;
24750
c248bee52dc6 Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents: 24747
diff changeset
1234 }
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
1235
52284
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1236 /* Shift digit vector a[0:m] d bits left, with 0 <= d < PyLong_SHIFT. Put
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1237 * result in z[0:m], and return the d bits shifted out of the top.
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1238 */
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1239 static digit
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1240 v_lshift(digit *z, digit *a, Py_ssize_t m, int d)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1241 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1242 Py_ssize_t i;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1243 digit carry = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1244
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1245 assert(0 <= d && d < PyLong_SHIFT);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1246 for (i=0; i < m; i++) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1247 twodigits acc = (twodigits)a[i] << d | carry;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1248 z[i] = (digit)acc & PyLong_MASK;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1249 carry = (digit)(acc >> PyLong_SHIFT);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1250 }
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1251 return carry;
52284
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1252 }
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1253
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1254 /* Shift digit vector a[0:m] d bits right, with 0 <= d < PyLong_SHIFT. Put
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1255 * result in z[0:m], and return the d bits shifted out of the bottom.
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1256 */
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1257 static digit
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1258 v_rshift(digit *z, digit *a, Py_ssize_t m, int d)
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
1259 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1260 Py_ssize_t i;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1261 digit carry = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1262 digit mask = ((digit)1 << d) - 1U;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1263
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1264 assert(0 <= d && d < PyLong_SHIFT);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1265 for (i=m; i-- > 0;) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1266 twodigits acc = (twodigits)carry << PyLong_SHIFT | a[i];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1267 carry = (digit)acc & mask;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1268 z[i] = (digit)(acc >> d);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1269 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1270 return carry;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1271 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1272
18594
19250f9181dc divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents: 18593
diff changeset
1273 /* Divide long pin, w/ size digits, by non-zero digit n, storing quotient
19250f9181dc divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents: 18593
diff changeset
1274 in pout, and returning the remainder. pin and pout point at the LSD.
19250f9181dc divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents: 18593
diff changeset
1275 It's OK for pin == pout on entry, which saves oodles of mallocs/frees in
45262
86906a5ceca6 Added PyNumber_ToBase and supporting routines _PyInt_Format and
Eric Smith <eric@trueblade.com>
parents: 44945
diff changeset
1276 _PyLong_Format, but that should be done with great care since longs are
18594
19250f9181dc divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents: 18593
diff changeset
1277 immutable. */
19250f9181dc divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents: 18593
diff changeset
1278
19250f9181dc divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents: 18593
diff changeset
1279 static digit
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
1280 inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n)
18594
19250f9181dc divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents: 18593
diff changeset
1281 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1282 twodigits rem = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1283
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1284 assert(n > 0 && n <= PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1285 pin += size;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1286 pout += size;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1287 while (--size >= 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1288 digit hi;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1289 rem = (rem << PyLong_SHIFT) | *--pin;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1290 *--pout = hi = (digit)(rem / n);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1291 rem -= (twodigits)hi * n;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1292 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1293 return (digit)rem;
18594
19250f9181dc divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents: 18593
diff changeset
1294 }
19250f9181dc divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents: 18593
diff changeset
1295
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1296 /* Divide a long integer by a digit, returning both the quotient
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1297 (as function result) and the remainder (through *prem).
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1298 The sign of a is ignored; n should not be zero. */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1299
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
1300 static PyLongObject *
18594
19250f9181dc divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents: 18593
diff changeset
1301 divrem1(PyLongObject *a, digit n, digit *prem)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1302 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1303 const Py_ssize_t size = ABS(Py_SIZE(a));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1304 PyLongObject *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1305
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1306 assert(n > 0 && n <= PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1307 z = _PyLong_New(size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1308 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1309 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1310 *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1311 return long_normalize(z);
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1312 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1313
56019
a2cbb9421a11 Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents: 55935
diff changeset
1314 /* Convert a long integer to a base 10 string. Returns a new non-shared
a2cbb9421a11 Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents: 55935
diff changeset
1315 string. (Return value is non-shared so that callers can modify the
a2cbb9421a11 Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents: 55935
diff changeset
1316 returned value if necessary.) */
a2cbb9421a11 Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents: 55935
diff changeset
1317
a2cbb9421a11 Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents: 55935
diff changeset
1318 static PyObject *
a2cbb9421a11 Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents: 55935
diff changeset
1319 long_to_decimal_string(PyObject *aa, int addL)
a2cbb9421a11 Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents: 55935
diff changeset
1320 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1321 PyLongObject *scratch, *a;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1322 PyObject *str;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1323 Py_ssize_t size, strlen, size_a, i, j;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1324 digit *pout, *pin, rem, tenpow;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1325 char *p;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1326 int negative;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1327
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1328 a = (PyLongObject *)aa;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1329 if (a == NULL || !PyLong_Check(a)) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1330 PyErr_BadInternalCall();
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1331 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1332 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1333 size_a = ABS(Py_SIZE(a));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1334 negative = Py_SIZE(a) < 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1335
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1336 /* quick and dirty upper bound for the number of digits
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1337 required to express a in base _PyLong_DECIMAL_BASE:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1338
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1339 #digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE))
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1340
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1341 But log2(a) < size_a * PyLong_SHIFT, and
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1342 log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1343 > 3 * _PyLong_DECIMAL_SHIFT
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1344 */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1345 if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1346 PyErr_SetString(PyExc_OverflowError,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1347 "long is too large to format");
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1348 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1349 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1350 /* the expression size_a * PyLong_SHIFT is now safe from overflow */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1351 size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1352 scratch = _PyLong_New(size);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1353 if (scratch == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1354 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1355
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1356 /* convert array of base _PyLong_BASE digits in pin to an array of
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1357 base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1358 Volume 2 (3rd edn), section 4.4, Method 1b). */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1359 pin = a->ob_digit;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1360 pout = scratch->ob_digit;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1361 size = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1362 for (i = size_a; --i >= 0; ) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1363 digit hi = pin[i];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1364 for (j = 0; j < size; j++) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1365 twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1366 hi = (digit)(z / _PyLong_DECIMAL_BASE);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1367 pout[j] = (digit)(z - (twodigits)hi *
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1368 _PyLong_DECIMAL_BASE);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1369 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1370 while (hi) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1371 pout[size++] = hi % _PyLong_DECIMAL_BASE;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1372 hi /= _PyLong_DECIMAL_BASE;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1373 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1374 /* check for keyboard interrupt */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1375 SIGCHECK({
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1376 Py_DECREF(scratch);
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1377 return NULL;
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
1378 });
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1379 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1380 /* pout should have at least one digit, so that the case when a = 0
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1381 works correctly */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1382 if (size == 0)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1383 pout[size++] = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1384
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1385 /* calculate exact length of output string, and allocate */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1386 strlen = (addL != 0) + negative +
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1387 1 + (size - 1) * _PyLong_DECIMAL_SHIFT;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1388 tenpow = 10;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1389 rem = pout[size-1];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1390 while (rem >= tenpow) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1391 tenpow *= 10;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1392 strlen++;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1393 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1394 str = PyString_FromStringAndSize(NULL, strlen);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1395 if (str == NULL) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1396 Py_DECREF(scratch);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1397 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1398 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1399
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1400 /* fill the string right-to-left */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1401 p = PyString_AS_STRING(str) + strlen;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1402 *p = '\0';
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1403 if (addL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1404 *--p = 'L';
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1405 /* pout[0] through pout[size-2] contribute exactly
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1406 _PyLong_DECIMAL_SHIFT digits each */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1407 for (i=0; i < size - 1; i++) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1408 rem = pout[i];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1409 for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1410 *--p = '0' + rem % 10;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1411 rem /= 10;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1412 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1413 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1414 /* pout[size-1]: always produce at least one decimal digit */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1415 rem = pout[i];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1416 do {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1417 *--p = '0' + rem % 10;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1418 rem /= 10;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1419 } while (rem != 0);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1420
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1421 /* and sign */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1422 if (negative)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1423 *--p = '-';
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1424
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1425 /* check we've counted correctly */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1426 assert(p == PyString_AS_STRING(str));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1427 Py_DECREF(scratch);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1428 return (PyObject *)str;
56019
a2cbb9421a11 Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents: 55935
diff changeset
1429 }
a2cbb9421a11 Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents: 55935
diff changeset
1430
45262
86906a5ceca6 Added PyNumber_ToBase and supporting routines _PyInt_Format and
Eric Smith <eric@trueblade.com>
parents: 44945
diff changeset
1431 /* Convert the long to a string object with given base,
86906a5ceca6 Added PyNumber_ToBase and supporting routines _PyInt_Format and
Eric Smith <eric@trueblade.com>
parents: 44945
diff changeset
1432 appending a base prefix of 0[box] if base is 2, 8 or 16.
86906a5ceca6 Added PyNumber_ToBase and supporting routines _PyInt_Format and
Eric Smith <eric@trueblade.com>
parents: 44945
diff changeset
1433 Add a trailing "L" if addL is non-zero.
86906a5ceca6 Added PyNumber_ToBase and supporting routines _PyInt_Format and
Eric Smith <eric@trueblade.com>
parents: 44945
diff changeset
1434 If newstyle is zero, then use the pre-2.6 behavior of octal having
86906a5ceca6 Added PyNumber_ToBase and supporting routines _PyInt_Format and
Eric Smith <eric@trueblade.com>
parents: 44945
diff changeset
1435 a leading "0", instead of the prefix "0o" */
86906a5ceca6 Added PyNumber_ToBase and supporting routines _PyInt_Format and
Eric Smith <eric@trueblade.com>
parents: 44945
diff changeset
1436 PyAPI_FUNC(PyObject *)
86906a5ceca6 Added PyNumber_ToBase and supporting routines _PyInt_Format and
Eric Smith <eric@trueblade.com>
parents: 44945
diff changeset
1437 _PyLong_Format(PyObject *aa, int base, int addL, int newstyle)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1438 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1439 register PyLongObject *a = (PyLongObject *)aa;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1440 PyStringObject *str;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1441 Py_ssize_t i, sz;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1442 Py_ssize_t size_a;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1443 char *p;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1444 int bits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1445 char sign = '\0';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1446
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1447 if (base == 10)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1448 return long_to_decimal_string((PyObject *)a, addL);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1449
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1450 if (a == NULL || !PyLong_Check(a)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1451 PyErr_BadInternalCall();
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1452 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1453 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1454 assert(base >= 2 && base <= 36);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1455 size_a = ABS(Py_SIZE(a));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1456
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1457 /* Compute a rough upper bound for the length of the string */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1458 i = base;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1459 bits = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1460 while (i > 1) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1461 ++bits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1462 i >>= 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1463 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1464 i = 5 + (addL ? 1 : 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1465 /* ensure we don't get signed overflow in sz calculation */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1466 if (size_a > (PY_SSIZE_T_MAX - i) / PyLong_SHIFT) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1467 PyErr_SetString(PyExc_OverflowError,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1468 "long is too large to format");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1469 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1470 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1471 sz = i + 1 + (size_a * PyLong_SHIFT - 1) / bits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1472 assert(sz >= 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1473 str = (PyStringObject *) PyString_FromStringAndSize((char *)0, sz);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1474 if (str == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1475 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1476 p = PyString_AS_STRING(str) + sz;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1477 *p = '\0';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1478 if (addL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1479 *--p = 'L';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1480 if (a->ob_size < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1481 sign = '-';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1482
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1483 if (a->ob_size == 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1484 *--p = '0';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1485 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1486 else if ((base & (base - 1)) == 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1487 /* JRH: special case for power-of-2 bases */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1488 twodigits accum = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1489 int accumbits = 0; /* # of bits in accum */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1490 int basebits = 1; /* # of bits in base-1 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1491 i = base;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1492 while ((i >>= 1) > 1)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1493 ++basebits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1494
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1495 for (i = 0; i < size_a; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1496 accum |= (twodigits)a->ob_digit[i] << accumbits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1497 accumbits += PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1498 assert(accumbits >= basebits);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1499 do {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1500 char cdigit = (char)(accum & (base - 1));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1501 cdigit += (cdigit < 10) ? '0' : 'a'-10;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1502 assert(p > PyString_AS_STRING(str));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1503 *--p = cdigit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1504 accumbits -= basebits;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1505 accum >>= basebits;
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1506 } while (i < size_a-1 ? accumbits >= basebits : accum > 0);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1507 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1508 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1509 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1510 /* Not 0, and base not a power of 2. Divide repeatedly by
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1511 base, but for speed use the highest power of base that
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1512 fits in a digit. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1513 Py_ssize_t size = size_a;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1514 digit *pin = a->ob_digit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1515 PyLongObject *scratch;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1516 /* powbasw <- largest power of base that fits in a digit. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1517 digit powbase = base; /* powbase == base ** power */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1518 int power = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1519 for (;;) {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
1520 twodigits newpow = powbase * (twodigits)base;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1521 if (newpow >> PyLong_SHIFT)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1522 /* doesn't fit in a digit */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1523 break;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1524 powbase = (digit)newpow;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1525 ++power;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1526 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1527
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1528 /* Get a scratch area for repeated division. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1529 scratch = _PyLong_New(size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1530 if (scratch == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1531 Py_DECREF(str);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1532 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1533 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1534
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1535 /* Repeatedly divide by powbase. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1536 do {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1537 int ntostore = power;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1538 digit rem = inplace_divrem1(scratch->ob_digit,
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1539 pin, size, powbase);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1540 pin = scratch->ob_digit; /* no need to use a again */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1541 if (pin[size - 1] == 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1542 --size;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1543 SIGCHECK({
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1544 Py_DECREF(scratch);
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1545 Py_DECREF(str);
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1546 return NULL;
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
1547 });
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1548
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1549 /* Break rem into digits. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1550 assert(ntostore > 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1551 do {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1552 digit nextrem = (digit)(rem / base);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1553 char c = (char)(rem - nextrem * base);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1554 assert(p > PyString_AS_STRING(str));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1555 c += (c < 10) ? '0' : 'a'-10;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1556 *--p = c;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1557 rem = nextrem;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1558 --ntostore;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1559 /* Termination is a bit delicate: must not
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1560 store leading zeroes, so must get out if
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1561 remaining quotient and rem are both 0. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1562 } while (ntostore && (size || rem));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1563 } while (size != 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1564 Py_DECREF(scratch);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1565 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1566
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1567 if (base == 2) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1568 *--p = 'b';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1569 *--p = '0';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1570 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1571 else if (base == 8) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1572 if (newstyle) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1573 *--p = 'o';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1574 *--p = '0';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1575 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1576 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1577 if (size_a != 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1578 *--p = '0';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1579 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1580 else if (base == 16) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1581 *--p = 'x';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1582 *--p = '0';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1583 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1584 else if (base != 10) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1585 *--p = '#';
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1586 *--p = '0' + base%10;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1587 if (base > 10)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1588 *--p = '0' + base/10;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1589 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1590 if (sign)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1591 *--p = sign;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1592 if (p != PyString_AS_STRING(str)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1593 char *q = PyString_AS_STRING(str);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1594 assert(p > q);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1595 do {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1596 } while ((*q++ = *p++) != '\0');
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1597 q--;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1598 _PyString_Resize((PyObject **)&str,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1599 (Py_ssize_t) (q - PyString_AS_STRING(str)));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1600 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1601 return (PyObject *)str;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1602 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1603
38301
dccbcbbd6720 A new table to help string->integer conversion was added yesterday to
Tim Peters <tim.peters@gmail.com>
parents: 38283
diff changeset
1604 /* Table of digit values for 8-bit string -> integer conversion.
dccbcbbd6720 A new table to help string->integer conversion was added yesterday to
Tim Peters <tim.peters@gmail.com>
parents: 38283
diff changeset
1605 * '0' maps to 0, ..., '9' maps to 9.
dccbcbbd6720 A new table to help string->integer conversion was added yesterday to
Tim Peters <tim.peters@gmail.com>
parents: 38283
diff changeset
1606 * 'a' and 'A' map to 10, ..., 'z' and 'Z' map to 35.
dccbcbbd6720 A new table to help string->integer conversion was added yesterday to
Tim Peters <tim.peters@gmail.com>
parents: 38283
diff changeset
1607 * All other indices map to 37.
dccbcbbd6720 A new table to help string->integer conversion was added yesterday to
Tim Peters <tim.peters@gmail.com>
parents: 38283
diff changeset
1608 * Note that when converting a base B string, a char c is a legitimate
dccbcbbd6720 A new table to help string->integer conversion was added yesterday to
Tim Peters <tim.peters@gmail.com>
parents: 38283
diff changeset
1609 * base B digit iff _PyLong_DigitValue[Py_CHARMASK(c)] < B.
dccbcbbd6720 A new table to help string->integer conversion was added yesterday to
Tim Peters <tim.peters@gmail.com>
parents: 38283
diff changeset
1610 */
dccbcbbd6720 A new table to help string->integer conversion was added yesterday to
Tim Peters <tim.peters@gmail.com>
parents: 38283
diff changeset
1611 int _PyLong_DigitValue[256] = {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1612 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1613 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1614 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1615 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 37, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1616 37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1617 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1618 37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1619 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1620 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1621 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1622 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1623 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1624 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1625 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1626 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1627 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
38283
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1628 };
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1629
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1630 /* *str points to the first digit in a string of base `base` digits. base
27587
7283140d4319 long(string, base) now takes time linear in len(string) when base is a
Tim Peters <tim.peters@gmail.com>
parents: 27585
diff changeset
1631 * is a power of 2 (2, 4, 8, 16, or 32). *str is set to point to the first
7283140d4319 long(string, base) now takes time linear in len(string) when base is a
Tim Peters <tim.peters@gmail.com>
parents: 27585
diff changeset
1632 * non-digit (which may be *str!). A normalized long is returned.
7283140d4319 long(string, base) now takes time linear in len(string) when base is a
Tim Peters <tim.peters@gmail.com>
parents: 27585
diff changeset
1633 * The point to this routine is that it takes time linear in the number of
7283140d4319 long(string, base) now takes time linear in len(string) when base is a
Tim Peters <tim.peters@gmail.com>
parents: 27585
diff changeset
1634 * string characters.
7283140d4319 long(string, base) now takes time linear in len(string) when base is a
Tim Peters <tim.peters@gmail.com>
parents: 27585
diff changeset
1635 */
7283140d4319 long(string, base) now takes time linear in len(string) when base is a
Tim Peters <tim.peters@gmail.com>
parents: 27585
diff changeset
1636 static PyLongObject *
7283140d4319 long(string, base) now takes time linear in len(string) when base is a
Tim Peters <tim.peters@gmail.com>
parents: 27585
diff changeset
1637 long_from_binary_base(char **str, int base)
7283140d4319 long(string, base) now takes time linear in len(string) when base is a
Tim Peters <tim.peters@gmail.com>
parents: 27585
diff changeset
1638 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1639 char *p = *str;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1640 char *start = p;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1641 int bits_per_char;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1642 Py_ssize_t n;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1643 PyLongObject *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1644 twodigits accum;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1645 int bits_in_accum;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1646 digit *pdigit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1647
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1648 assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1649 n = base;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1650 for (bits_per_char = -1; n; ++bits_per_char)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1651 n >>= 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1652 /* n <- total # of bits needed, while setting p to end-of-string */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1653 while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1654 ++p;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1655 *str = p;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1656 /* n <- # of Python digits needed, = ceiling(n/PyLong_SHIFT). */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1657 n = (p - start) * bits_per_char + PyLong_SHIFT - 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1658 if (n / bits_per_char < p - start) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1659 PyErr_SetString(PyExc_ValueError,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1660 "long string too large to convert");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1661 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1662 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1663 n = n / PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1664 z = _PyLong_New(n);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1665 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1666 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1667 /* Read string from right, and fill in long from left; i.e.,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1668 * from least to most significant in both.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1669 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1670 accum = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1671 bits_in_accum = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1672 pdigit = z->ob_digit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1673 while (--p >= start) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1674 int k = _PyLong_DigitValue[Py_CHARMASK(*p)];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1675 assert(k >= 0 && k < base);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1676 accum |= (twodigits)k << bits_in_accum;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1677 bits_in_accum += bits_per_char;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1678 if (bits_in_accum >= PyLong_SHIFT) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1679 *pdigit++ = (digit)(accum & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1680 assert(pdigit - z->ob_digit <= n);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1681 accum >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1682 bits_in_accum -= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1683 assert(bits_in_accum < PyLong_SHIFT);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1684 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1685 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1686 if (bits_in_accum) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1687 assert(bits_in_accum <= PyLong_SHIFT);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1688 *pdigit++ = (digit)accum;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1689 assert(pdigit - z->ob_digit <= n);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1690 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1691 while (pdigit - z->ob_digit < n)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1692 *pdigit++ = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1693 return long_normalize(z);
27587
7283140d4319 long(string, base) now takes time linear in len(string) when base is a
Tim Peters <tim.peters@gmail.com>
parents: 27585
diff changeset
1694 }
7283140d4319 long(string, base) now takes time linear in len(string) when base is a
Tim Peters <tim.peters@gmail.com>
parents: 27585
diff changeset
1695
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
1696 PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
1697 PyLong_FromString(char *str, char **pend, int base)
1837
87364d9e3444 New patches by Andrew to fix various problems
Guido van Rossum <guido@python.org>
parents: 1391
diff changeset
1698 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1699 int sign = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1700 char *start, *orig_str = str;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1701 PyLongObject *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1702 PyObject *strobj, *strrepr;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1703 Py_ssize_t slen;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1704
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1705 if ((base != 0 && base < 2) || base > 36) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1706 PyErr_SetString(PyExc_ValueError,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1707 "long() arg 2 must be >= 2 and <= 36");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1708 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1709 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1710 while (*str != '\0' && isspace(Py_CHARMASK(*str)))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1711 str++;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1712 if (*str == '+')
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1713 ++str;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1714 else if (*str == '-') {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1715 ++str;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1716 sign = -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1717 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1718 while (*str != '\0' && isspace(Py_CHARMASK(*str)))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1719 str++;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1720 if (base == 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1721 /* No base given. Deduce the base from the contents
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1722 of the string */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1723 if (str[0] != '0')
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1724 base = 10;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1725 else if (str[1] == 'x' || str[1] == 'X')
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1726 base = 16;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1727 else if (str[1] == 'o' || str[1] == 'O')
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1728 base = 8;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1729 else if (str[1] == 'b' || str[1] == 'B')
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1730 base = 2;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1731 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1732 /* "old" (C-style) octal literal, still valid in
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1733 2.x, although illegal in 3.x */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1734 base = 8;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1735 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1736 /* Whether or not we were deducing the base, skip leading chars
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1737 as needed */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1738 if (str[0] == '0' &&
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1739 ((base == 16 && (str[1] == 'x' || str[1] == 'X')) ||
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1740 (base == 8 && (str[1] == 'o' || str[1] == 'O')) ||
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1741 (base == 2 && (str[1] == 'b' || str[1] == 'B'))))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1742 str += 2;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1743
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1744 start = str;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1745 if ((base & (base - 1)) == 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1746 z = long_from_binary_base(&str, base);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1747 else {
38283
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1748 /***
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1749 Binary bases can be converted in time linear in the number of digits, because
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1750 Python's representation base is binary. Other bases (including decimal!) use
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1751 the simple quadratic-time algorithm below, complicated by some speed tricks.
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1752
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1753 First some math: the largest integer that can be expressed in N base-B digits
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1754 is B**N-1. Consequently, if we have an N-digit input in base B, the worst-
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1755 case number of Python digits needed to hold it is the smallest integer n s.t.
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1756
44945
bbc719a8b58b Backport of several functions from Python 3.0 to 2.6 including PyUnicode_FromString, PyUnicode_Format and PyLong_From/AsSsize_t. The functions are partly required for the backport of the bytearray type and _fileio module. They should also make it easier to port C to 3.0.
Christian Heimes <christian@cheimes.de>
parents: 44749
diff changeset
1757 PyLong_BASE**n-1 >= B**N-1 [or, adding 1 to both sides]
bbc719a8b58b Backport of several functions from Python 3.0 to 2.6 including PyUnicode_FromString, PyUnicode_Format and PyLong_From/AsSsize_t. The functions are partly required for the backport of the bytearray type and _fileio module. They should also make it easier to port C to 3.0.
Christian Heimes <christian@cheimes.de>
parents: 44749
diff changeset
1758 PyLong_BASE**n >= B**N [taking logs to base PyLong_BASE]
bbc719a8b58b Backport of several functions from Python 3.0 to 2.6 including PyUnicode_FromString, PyUnicode_Format and PyLong_From/AsSsize_t. The functions are partly required for the backport of the bytearray type and _fileio module. They should also make it easier to port C to 3.0.
Christian Heimes <christian@cheimes.de>
parents: 44749
diff changeset
1759 n >= log(B**N)/log(PyLong_BASE) = N * log(B)/log(PyLong_BASE)
bbc719a8b58b Backport of several functions from Python 3.0 to 2.6 including PyUnicode_FromString, PyUnicode_Format and PyLong_From/AsSsize_t. The functions are partly required for the backport of the bytearray type and _fileio module. They should also make it easier to port C to 3.0.
Christian Heimes <christian@cheimes.de>
parents: 44749
diff changeset
1760
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1761 The static array log_base_PyLong_BASE[base] == log(base)/log(PyLong_BASE) so
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1762 we can compute this quickly. A Python long with that much space is reserved
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1763 near the start, and the result is computed into it.
38283
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1764
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1765 The input string is actually treated as being in base base**i (i.e., i digits
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1766 are processed at a time), where two more static arrays hold:
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1767
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1768 convwidth_base[base] = the largest integer i such that
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1769 base**i <= PyLong_BASE
38283
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1770 convmultmax_base[base] = base ** convwidth_base[base]
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1771
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1772 The first of these is the largest i such that i consecutive input digits
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1773 must fit in a single Python digit. The second is effectively the input
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1774 base we're really using.
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1775
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1776 Viewing the input as a sequence <c0, c1, ..., c_n-1> of digits in base
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1777 convmultmax_base[base], the result is "simply"
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1778
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1779 (((c0*B + c1)*B + c2)*B + c3)*B + ... ))) + c_n-1
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1780
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1781 where B = convmultmax_base[base].
38513
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1782
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1783 Error analysis: as above, the number of Python digits `n` needed is worst-
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1784 case
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1785
44945
bbc719a8b58b Backport of several functions from Python 3.0 to 2.6 including PyUnicode_FromString, PyUnicode_Format and PyLong_From/AsSsize_t. The functions are partly required for the backport of the bytearray type and _fileio module. They should also make it easier to port C to 3.0.
Christian Heimes <christian@cheimes.de>
parents: 44749
diff changeset
1786 n >= N * log(B)/log(PyLong_BASE)
38513
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1787
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1788 where `N` is the number of input digits in base `B`. This is computed via
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1789
44945
bbc719a8b58b Backport of several functions from Python 3.0 to 2.6 including PyUnicode_FromString, PyUnicode_Format and PyLong_From/AsSsize_t. The functions are partly required for the backport of the bytearray type and _fileio module. They should also make it easier to port C to 3.0.
Christian Heimes <christian@cheimes.de>
parents: 44749
diff changeset
1790 size_z = (Py_ssize_t)((scan - str) * log_base_PyLong_BASE[base]) + 1;
38513
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1791
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1792 below. Two numeric concerns are how much space this can waste, and whether
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1793 the computed result can be too small. To be concrete, assume PyLong_BASE =
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1794 2**15, which is the default (and it's unlikely anyone changes that).
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1795
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1796 Waste isn't a problem: provided the first input digit isn't 0, the difference
38513
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1797 between the worst-case input with N digits and the smallest input with N
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1798 digits is about a factor of B, but B is small compared to PyLong_BASE so at
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1799 most one allocated Python digit can remain unused on that count. If
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1800 N*log(B)/log(PyLong_BASE) is mathematically an exact integer, then truncating
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1801 that and adding 1 returns a result 1 larger than necessary. However, that
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1802 can't happen: whenever B is a power of 2, long_from_binary_base() is called
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1803 instead, and it's impossible for B**i to be an integer power of 2**15 when B
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1804 is not a power of 2 (i.e., it's impossible for N*log(B)/log(PyLong_BASE) to be
38513
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1805 an exact integer when B is not a power of 2, since B**i has a prime factor
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1806 other than 2 in that case, but (2**15)**j's only prime factor is 2).
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1807
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1808 The computed result can be too small if the true value of
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1809 N*log(B)/log(PyLong_BASE) is a little bit larger than an exact integer, but
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1810 due to roundoff errors (in computing log(B), log(PyLong_BASE), their quotient,
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1811 and/or multiplying that by N) yields a numeric result a little less than that
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1812 integer. Unfortunately, "how close can a transcendental function get to an
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1813 integer over some range?" questions are generally theoretically intractable.
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1814 Computer analysis via continued fractions is practical: expand
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1815 log(B)/log(PyLong_BASE) via continued fractions, giving a sequence i/j of "the
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1816 best" rational approximations. Then j*log(B)/log(PyLong_BASE) is
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1817 approximately equal to (the integer) i. This shows that we can get very close
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1818 to being in trouble, but very rarely. For example, 76573 is a denominator in
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1819 one of the continued-fraction approximations to log(10)/log(2**15), and
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1820 indeed:
38513
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1821
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1822 >>> log(10)/log(2**15)*76573
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1823 16958.000000654003
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1824
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1825 is very close to an integer. If we were working with IEEE single-precision,
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1826 rounding errors could kill us. Finding worst cases in IEEE double-precision
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1827 requires better-than-double-precision log() functions, and Tim didn't bother.
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1828 Instead the code checks to see whether the allocated space is enough as each
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1829 new Python digit is added, and copies the whole thing to a larger long if not.
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1830 This should happen extremely rarely, and in fact I don't have a test case
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1831 that triggers it(!). Instead the code was tested by artificially allocating
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1832 just 1 digit at the start, so that the copying code was exercised for every
7f1f36b3c9f9 PyLong_FromString(): Continued fraction analysis (explained in
Tim Peters <tim.peters@gmail.com>
parents: 38331
diff changeset
1833 digit beyond the first.
38283
88cc7e4f01ff Heavily fiddled variant of patch #1442927: PyLong_FromString optimization.
Tim Peters <tim.peters@gmail.com>
parents: 38139
diff changeset
1834 ***/
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1835 register twodigits c; /* current input character */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1836 Py_ssize_t size_z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1837 int i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1838 int convwidth;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1839 twodigits convmultmax, convmult;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1840 digit *pz, *pzstop;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1841 char* scan;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1842
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1843 static double log_base_PyLong_BASE[37] = {0.0e0,};
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1844 static int convwidth_base[37] = {0,};
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1845 static twodigits convmultmax_base[37] = {0,};
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1846
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1847 if (log_base_PyLong_BASE[base] == 0.0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1848 twodigits convmax = base;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1849 int i = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1850
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1851 log_base_PyLong_BASE[base] = (log((double)base) /
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1852 log((double)PyLong_BASE));
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1853 for (;;) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1854 twodigits next = convmax * base;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1855 if (next > PyLong_BASE)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1856 break;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1857 convmax = next;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1858 ++i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1859 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1860 convmultmax_base[base] = convmax;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1861 assert(i > 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1862 convwidth_base[base] = i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1863 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1864
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1865 /* Find length of the string of numeric characters. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1866 scan = str;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1867 while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1868 ++scan;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1869
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1870 /* Create a long object that can contain the largest possible
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1871 * integer with this base and length. Note that there's no
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1872 * need to initialize z->ob_digit -- no slot is read up before
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1873 * being stored into.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1874 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1875 size_z = (Py_ssize_t)((scan - str) * log_base_PyLong_BASE[base]) + 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1876 /* Uncomment next line to test exceedingly rare copy code */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1877 /* size_z = 1; */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1878 assert(size_z > 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1879 z = _PyLong_New(size_z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1880 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1881 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1882 Py_SIZE(z) = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1883
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1884 /* `convwidth` consecutive input digits are treated as a single
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1885 * digit in base `convmultmax`.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1886 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1887 convwidth = convwidth_base[base];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1888 convmultmax = convmultmax_base[base];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1889
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1890 /* Work ;-) */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1891 while (str < scan) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1892 /* grab up to convwidth digits from the input string */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1893 c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1894 for (i = 1; i < convwidth && str != scan; ++i, ++str) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1895 c = (twodigits)(c * base +
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1896 _PyLong_DigitValue[Py_CHARMASK(*str)]);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1897 assert(c < PyLong_BASE);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1898 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1899
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1900 convmult = convmultmax;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1901 /* Calculate the shift only if we couldn't get
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1902 * convwidth digits.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1903 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1904 if (i != convwidth) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1905 convmult = base;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1906 for ( ; i > 1; --i)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1907 convmult *= base;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1908 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1909
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1910 /* Multiply z by convmult, and add c. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1911 pz = z->ob_digit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1912 pzstop = pz + Py_SIZE(z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1913 for (; pz < pzstop; ++pz) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1914 c += (twodigits)*pz * convmult;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1915 *pz = (digit)(c & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1916 c >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1917 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1918 /* carry off the current end? */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1919 if (c) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1920 assert(c < PyLong_BASE);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1921 if (Py_SIZE(z) < size_z) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1922 *pz = (digit)c;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1923 ++Py_SIZE(z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1924 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1925 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1926 PyLongObject *tmp;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1927 /* Extremely rare. Get more space. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1928 assert(Py_SIZE(z) == size_z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1929 tmp = _PyLong_New(size_z + 1);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1930 if (tmp == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1931 Py_DECREF(z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1932 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1933 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1934 memcpy(tmp->ob_digit,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1935 z->ob_digit,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1936 sizeof(digit) * size_z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1937 Py_DECREF(z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1938 z = tmp;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1939 z->ob_digit[size_z] = (digit)c;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1940 ++size_z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1941 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1942 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1943 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1944 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1945 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1946 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1947 if (str == start)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1948 goto onError;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1949 if (sign < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1950 Py_SIZE(z) = -(Py_SIZE(z));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1951 if (*str == 'L' || *str == 'l')
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1952 str++;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1953 while (*str && isspace(Py_CHARMASK(*str)))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1954 str++;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1955 if (*str != '\0')
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1956 goto onError;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1957 if (pend)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1958 *pend = str;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1959 return (PyObject *) z;
12248
70154e2e9c89 Marc-Andre's third try at this bulk patch seems to work (except that
Guido van Rossum <guido@python.org>
parents: 11628
diff changeset
1960
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
1961 onError:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1962 Py_XDECREF(z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1963 slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1964 strobj = PyString_FromStringAndSize(orig_str, slen);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1965 if (strobj == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1966 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1967 strrepr = PyObject_Repr(strobj);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1968 Py_DECREF(strobj);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1969 if (strrepr == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1970 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1971 PyErr_Format(PyExc_ValueError,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1972 "invalid literal for long() with base %d: %s",
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1973 base, PyString_AS_STRING(strrepr));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1974 Py_DECREF(strrepr);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1975 return NULL;
12248
70154e2e9c89 Marc-Andre's third try at this bulk patch seems to work (except that
Guido van Rossum <guido@python.org>
parents: 11628
diff changeset
1976 }
70154e2e9c89 Marc-Andre's third try at this bulk patch seems to work (except that
Guido van Rossum <guido@python.org>
parents: 11628
diff changeset
1977
19343
7257e87e0720 Patch #445762: Support --disable-unicode
Martin v. Löwis <martin@v.loewis.de>
parents: 19051
diff changeset
1978 #ifdef Py_USING_UNICODE
12248
70154e2e9c89 Marc-Andre's third try at this bulk patch seems to work (except that
Guido van Rossum <guido@python.org>
parents: 11628
diff changeset
1979 PyObject *
36501
7fdc639bc5b4 Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents: 36430
diff changeset
1980 PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
12248
70154e2e9c89 Marc-Andre's third try at this bulk patch seems to work (except that
Guido van Rossum <guido@python.org>
parents: 11628
diff changeset
1981 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1982 PyObject *result;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1983 char *buffer = (char *)PyMem_MALLOC(length+1);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1984
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1985 if (buffer == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1986 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1987
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1988 if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1989 PyMem_FREE(buffer);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1990 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1991 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1992 result = PyLong_FromString(buffer, NULL, base);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1993 PyMem_FREE(buffer);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
1994 return result;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1995 }
19343
7257e87e0720 Patch #445762: Support --disable-unicode
Martin v. Löwis <martin@v.loewis.de>
parents: 19051
diff changeset
1996 #endif
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1997
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
1998 /* forward */
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
1999 static PyLongObject *x_divrem
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2000 (PyLongObject *, PyLongObject *, PyLongObject **);
44432
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
2001 static PyObject *long_long(PyObject *v);
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2002
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2003 /* Long division with remainder, top-level routine */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2004
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
2005 static int
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
2006 long_divrem(PyLongObject *a, PyLongObject *b,
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2007 PyLongObject **pdiv, PyLongObject **prem)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2008 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2009 Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2010 PyLongObject *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2011
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2012 if (size_b == 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2013 PyErr_SetString(PyExc_ZeroDivisionError,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2014 "long division or modulo by zero");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2015 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2016 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2017 if (size_a < size_b ||
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2018 (size_a == size_b &&
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2019 a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2020 /* |a| < |b|. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2021 *pdiv = _PyLong_New(0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2022 if (*pdiv == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2023 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2024 Py_INCREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2025 *prem = (PyLongObject *) a;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2026 return 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2027 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2028 if (size_b == 1) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2029 digit rem = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2030 z = divrem1(a, b->ob_digit[0], &rem);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2031 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2032 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2033 *prem = (PyLongObject *) PyLong_FromLong((long)rem);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2034 if (*prem == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2035 Py_DECREF(z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2036 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2037 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2038 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2039 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2040 z = x_divrem(a, b, prem);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2041 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2042 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2043 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2044 /* Set the signs.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2045 The quotient z has the sign of a*b;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2046 the remainder r has the sign of a,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2047 so a = b*z + r. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2048 if ((a->ob_size < 0) != (b->ob_size < 0))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2049 z->ob_size = -(z->ob_size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2050 if (a->ob_size < 0 && (*prem)->ob_size != 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2051 (*prem)->ob_size = -((*prem)->ob_size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2052 *pdiv = z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2053 return 0;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2054 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2055
52284
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
2056 /* Unsigned long division with remainder -- the algorithm. The arguments v1
a54ef18ab0d8 Issue #5512: speed up the long division algorithm for Python longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 52233
diff changeset
2057 and w1 should satisfy 2 <= ABS(Py_SIZE(w1)) <= ABS(Py_SIZE(v1)). */
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2058
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
2059 static PyLongObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
2060 x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2061 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2062 PyLongObject *v, *w, *a;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2063 Py_ssize_t i, k, size_v, size_w;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2064 int d;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2065 digit wm1, wm2, carry, q, r, vtop, *v0, *vk, *w0, *ak;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2066 twodigits vv;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2067 sdigit zhi;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2068 stwodigits z;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2069
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2070 /* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2071 edn.), section 4.3.1, Algorithm D], except that we don't explicitly
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2072 handle the special case when the initial estimate q for a quotient
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2073 digit is >= PyLong_BASE: the max value for q is PyLong_BASE+1, and
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2074 that won't overflow a digit. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2075
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2076 /* allocate space; w will also be used to hold the final remainder */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2077 size_v = ABS(Py_SIZE(v1));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2078 size_w = ABS(Py_SIZE(w1));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2079 assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2080 v = _PyLong_New(size_v+1);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2081 if (v == NULL) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2082 *prem = NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2083 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2084 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2085 w = _PyLong_New(size_w);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2086 if (w == NULL) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2087 Py_DECREF(v);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2088 *prem = NULL;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2089 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2090 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2091
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2092 /* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2.
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2093 shift v1 left by the same amount. Results go into w and v. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2094 d = PyLong_SHIFT - bits_in_digit(w1->ob_digit[size_w-1]);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2095 carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2096 assert(carry == 0);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2097 carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2098 if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2099 v->ob_digit[size_v] = carry;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2100 size_v++;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2101 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2102
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2103 /* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2104 at most (and usually exactly) k = size_v - size_w digits. */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2105 k = size_v - size_w;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2106 assert(k >= 0);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2107 a = _PyLong_New(k);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2108 if (a == NULL) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2109 Py_DECREF(w);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2110 Py_DECREF(v);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2111 *prem = NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2112 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2113 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2114 v0 = v->ob_digit;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2115 w0 = w->ob_digit;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2116 wm1 = w0[size_w-1];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2117 wm2 = w0[size_w-2];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2118 for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2119 /* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2120 single-digit quotient q, remainder in vk[0:size_w]. */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2121
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2122 SIGCHECK({
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2123 Py_DECREF(a);
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2124 Py_DECREF(w);
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2125 Py_DECREF(v);
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2126 *prem = NULL;
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2127 return NULL;
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
2128 });
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2129
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2130 /* estimate quotient digit q; may overestimate by 1 (rare) */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2131 vtop = vk[size_w];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2132 assert(vtop <= wm1);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2133 vv = ((twodigits)vtop << PyLong_SHIFT) | vk[size_w-1];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2134 q = (digit)(vv / wm1);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2135 r = (digit)(vv - (twodigits)wm1 * q); /* r = vv % wm1 */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2136 while ((twodigits)wm2 * q > (((twodigits)r << PyLong_SHIFT)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2137 | vk[size_w-2])) {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2138 --q;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2139 r += wm1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2140 if (r >= PyLong_BASE)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2141 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2142 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2143 assert(q <= PyLong_BASE);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2144
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2145 /* subtract q*w0[0:size_w] from vk[0:size_w+1] */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2146 zhi = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2147 for (i = 0; i < size_w; ++i) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2148 /* invariants: -PyLong_BASE <= -q <= zhi <= 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2149 -PyLong_BASE * q <= z < PyLong_BASE */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2150 z = (sdigit)vk[i] + zhi -
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2151 (stwodigits)q * (stwodigits)w0[i];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2152 vk[i] = (digit)z & PyLong_MASK;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2153 zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits,
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2154 z, PyLong_SHIFT);
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2155 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2156
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2157 /* add w back if q was too large (this branch taken rarely) */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2158 assert((sdigit)vtop + zhi == -1 || (sdigit)vtop + zhi == 0);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2159 if ((sdigit)vtop + zhi < 0) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2160 carry = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2161 for (i = 0; i < size_w; ++i) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2162 carry += vk[i] + w0[i];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2163 vk[i] = carry & PyLong_MASK;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2164 carry >>= PyLong_SHIFT;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2165 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2166 --q;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2167 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2168
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2169 /* store quotient digit */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2170 assert(q < PyLong_BASE);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2171 *--ak = q;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2172 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2173
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2174 /* unshift remainder; we reuse w to store the result */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2175 carry = v_rshift(w0, v0, size_w, d);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2176 assert(carry==0);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2177 Py_DECREF(v);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2178
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2179 *prem = long_normalize(w);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2180 return long_normalize(a);
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2181 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2182
58085
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2183 /* For a nonzero PyLong a, express a in the form x * 2**e, with 0.5 <=
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2184 abs(x) < 1.0 and e >= 0; return x and put e in *e. Here x is
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2185 rounded to DBL_MANT_DIG significant bits using round-half-to-even.
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2186 If a == 0, return 0.0 and set *e = 0. If the resulting exponent
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2187 e is larger than PY_SSIZE_T_MAX, raise OverflowError and return
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2188 -1.0. */
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2189
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2190 /* attempt to define 2.0**DBL_MANT_DIG as a compile-time constant */
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2191 #if DBL_MANT_DIG == 53
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2192 #define EXP2_DBL_MANT_DIG 9007199254740992.0
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2193 #else
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2194 #define EXP2_DBL_MANT_DIG (ldexp(1.0, DBL_MANT_DIG))
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2195 #endif
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2196
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2197 double
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2198 _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e)
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2199 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2200 Py_ssize_t a_size, a_bits, shift_digits, shift_bits, x_size;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2201 /* See below for why x_digits is always large enough. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2202 digit rem, x_digits[2 + (DBL_MANT_DIG + 1) / PyLong_SHIFT];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2203 double dx;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2204 /* Correction term for round-half-to-even rounding. For a digit x,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2205 "x + half_even_correction[x & 7]" gives x rounded to the nearest
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2206 multiple of 4, rounding ties to a multiple of 8. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2207 static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1};
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2208
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2209 a_size = ABS(Py_SIZE(a));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2210 if (a_size == 0) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2211 /* Special case for 0: significand 0.0, exponent 0. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2212 *e = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2213 return 0.0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2214 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2215 a_bits = bits_in_digit(a->ob_digit[a_size-1]);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2216 /* The following is an overflow-free version of the check
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2217 "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2218 if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 &&
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2219 (a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 ||
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2220 a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1))
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2221 goto overflow;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2222 a_bits = (a_size - 1) * PyLong_SHIFT + a_bits;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2223
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2224 /* Shift the first DBL_MANT_DIG + 2 bits of a into x_digits[0:x_size]
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2225 (shifting left if a_bits <= DBL_MANT_DIG + 2).
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2226
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2227 Number of digits needed for result: write // for floor division.
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2228 Then if shifting left, we end up using
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2229
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2230 1 + a_size + (DBL_MANT_DIG + 2 - a_bits) // PyLong_SHIFT
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2231
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2232 digits. If shifting right, we use
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2233
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2234 a_size - (a_bits - DBL_MANT_DIG - 2) // PyLong_SHIFT
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2235
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2236 digits. Using a_size = 1 + (a_bits - 1) // PyLong_SHIFT along with
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2237 the inequalities
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2238
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2239 m // PyLong_SHIFT + n // PyLong_SHIFT <= (m + n) // PyLong_SHIFT
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2240 m // PyLong_SHIFT - n // PyLong_SHIFT <=
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2241 1 + (m - n - 1) // PyLong_SHIFT,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2242
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2243 valid for any integers m and n, we find that x_size satisfies
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2244
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2245 x_size <= 2 + (DBL_MANT_DIG + 1) // PyLong_SHIFT
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2246
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2247 in both cases.
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2248 */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2249 if (a_bits <= DBL_MANT_DIG + 2) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2250 shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2251 shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2252 x_size = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2253 while (x_size < shift_digits)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2254 x_digits[x_size++] = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2255 rem = v_lshift(x_digits + x_size, a->ob_digit, a_size,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2256 (int)shift_bits);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2257 x_size += a_size;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2258 x_digits[x_size++] = rem;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2259 }
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2260 else {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2261 shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2262 shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2263 rem = v_rshift(x_digits, a->ob_digit + shift_digits,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2264 a_size - shift_digits, (int)shift_bits);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2265 x_size = a_size - shift_digits;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2266 /* For correct rounding below, we need the least significant
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2267 bit of x to be 'sticky' for this shift: if any of the bits
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2268 shifted out was nonzero, we set the least significant bit
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2269 of x. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2270 if (rem)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2271 x_digits[0] |= 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2272 else
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2273 while (shift_digits > 0)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2274 if (a->ob_digit[--shift_digits]) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2275 x_digits[0] |= 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2276 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2277 }
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2278 }
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2279 assert(1 <= x_size &&
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2280 x_size <= (Py_ssize_t)(sizeof(x_digits)/sizeof(digit)));
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2281
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2282 /* Round, and convert to double. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2283 x_digits[0] += half_even_correction[x_digits[0] & 7];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2284 dx = x_digits[--x_size];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2285 while (x_size > 0)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2286 dx = dx * PyLong_BASE + x_digits[--x_size];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2287
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2288 /* Rescale; make correction if result is 1.0. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2289 dx /= 4.0 * EXP2_DBL_MANT_DIG;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2290 if (dx == 1.0) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2291 if (a_bits == PY_SSIZE_T_MAX)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2292 goto overflow;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2293 dx = 0.5;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2294 a_bits += 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2295 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2296
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2297 *e = a_bits;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2298 return Py_SIZE(a) < 0 ? -dx : dx;
58085
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2299
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2300 overflow:
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2301 /* exponent > PY_SSIZE_T_MAX */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2302 PyErr_SetString(PyExc_OverflowError,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2303 "huge integer: number of bits overflows a Py_ssize_t");
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2304 *e = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2305 return -1.0;
58085
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2306 }
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2307
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2308 /* Get a C double from a long int object. Rounds to the nearest double,
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2309 using the round-half-to-even rule in the case of a tie. */
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2310
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2311 double
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2312 PyLong_AsDouble(PyObject *v)
27c946ff76a3 Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble
Mark Dickinson <dickinsm@gmail.com>
parents: 57941
diff changeset
2313 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2314 Py_ssize_t exponent;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2315 double x;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2316
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2317 if (v == NULL || !PyLong_Check(v)) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2318 PyErr_BadInternalCall();
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2319 return -1.0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2320 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2321 x = _PyLong_Frexp((PyLongObject *)v, &exponent);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2322 if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2323 PyErr_SetString(PyExc_OverflowError,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2324 "long int too large to convert to float");
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2325 return -1.0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2326 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2327 return ldexp(x, (int)exponent);
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2328 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2329
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2330 /* Methods */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2331
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2332 static void
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
2333 long_dealloc(PyObject *v)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2334 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2335 Py_TYPE(v)->tp_free(v);
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2336 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2337
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
2338 static PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
2339 long_repr(PyObject *v)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2340 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2341 return _PyLong_Format(v, 10, 1, 0);
11628
47f93a969366 long_format(): Now takes a third parameter, addL; iff true, a
Fred Drake <fdrake@acm.org>
parents: 11380
diff changeset
2342 }
47f93a969366 long_format(): Now takes a third parameter, addL; iff true, a
Fred Drake <fdrake@acm.org>
parents: 11380
diff changeset
2343
47f93a969366 long_format(): Now takes a third parameter, addL; iff true, a
Fred Drake <fdrake@acm.org>
parents: 11380
diff changeset
2344 static PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
2345 long_str(PyObject *v)
11628
47f93a969366 long_format(): Now takes a third parameter, addL; iff true, a
Fred Drake <fdrake@acm.org>
parents: 11380
diff changeset
2346 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2347 return _PyLong_Format(v, 10, 0, 0);
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2348 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2349
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2350 static int
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
2351 long_compare(PyLongObject *a, PyLongObject *b)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2352 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2353 Py_ssize_t sign;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2354
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2355 if (Py_SIZE(a) != Py_SIZE(b)) {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2356 sign = Py_SIZE(a) - Py_SIZE(b);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2357 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2358 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2359 Py_ssize_t i = ABS(Py_SIZE(a));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2360 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2361 ;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2362 if (i < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2363 sign = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2364 else {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2365 sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i];
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2366 if (Py_SIZE(a) < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2367 sign = -sign;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2368 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2369 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2370 return sign < 0 ? -1 : sign > 0 ? 1 : 0;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2371 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2372
1257
1cabc2b6c970 * Changed all copyright messages to include 1993.
Guido van Rossum <guido@python.org>
parents: 1252
diff changeset
2373 static long
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
2374 long_hash(PyLongObject *v)
1257
1cabc2b6c970 * Changed all copyright messages to include 1993.
Guido van Rossum <guido@python.org>
parents: 1252
diff changeset
2375 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2376 unsigned long x;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2377 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2378 int sign;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2379
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2380 /* This is designed so that Python ints and longs with the
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2381 same value hash to the same value, otherwise comparisons
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2382 of mapping keys will turn out weird */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2383 i = v->ob_size;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2384 sign = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2385 x = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2386 if (i < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2387 sign = -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2388 i = -(i);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2389 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2390 /* The following loop produces a C unsigned long x such that x is
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2391 congruent to the absolute value of v modulo ULONG_MAX. The
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2392 resulting x is nonzero if and only if v is. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2393 while (--i >= 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2394 /* Force a native long #-bits (32 or 64) circular shift */
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2395 x = (x >> (8*SIZEOF_LONG-PyLong_SHIFT)) | (x << PyLong_SHIFT);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2396 x += v->ob_digit[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2397 /* If the addition above overflowed we compensate by
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2398 incrementing. This preserves the value modulo
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2399 ULONG_MAX. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2400 if (x < v->ob_digit[i])
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2401 x++;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2402 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2403 x = x * sign;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2404 if (x == (unsigned long)-1)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2405 x = (unsigned long)-2;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
2406 return (long)x;
1257
1cabc2b6c970 * Changed all copyright messages to include 1993.
Guido van Rossum <guido@python.org>
parents: 1252
diff changeset
2407 }
1cabc2b6c970 * Changed all copyright messages to include 1993.
Guido van Rossum <guido@python.org>
parents: 1252
diff changeset
2408
1cabc2b6c970 * Changed all copyright messages to include 1993.
Guido van Rossum <guido@python.org>
parents: 1252
diff changeset
2409
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2410 /* Add the absolute values of two long integers. */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2411
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
2412 static PyLongObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
2413 x_add(PyLongObject *a, PyLongObject *b)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2414 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2415 Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2416 PyLongObject *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2417 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2418 digit carry = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2419
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2420 /* Ensure a is the larger of the two: */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2421 if (size_a < size_b) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2422 { PyLongObject *temp = a; a = b; b = temp; }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2423 { Py_ssize_t size_temp = size_a;
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2424 size_a = size_b;
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2425 size_b = size_temp; }
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2426 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2427 z = _PyLong_New(size_a+1);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2428 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2429 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2430 for (i = 0; i < size_b; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2431 carry += a->ob_digit[i] + b->ob_digit[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2432 z->ob_digit[i] = carry & PyLong_MASK;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2433 carry >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2434 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2435 for (; i < size_a; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2436 carry += a->ob_digit[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2437 z->ob_digit[i] = carry & PyLong_MASK;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2438 carry >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2439 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2440 z->ob_digit[i] = carry;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2441 return long_normalize(z);
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2442 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2443
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2444 /* Subtract the absolute values of two integers. */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2445
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
2446 static PyLongObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
2447 x_sub(PyLongObject *a, PyLongObject *b)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2448 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2449 Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2450 PyLongObject *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2451 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2452 int sign = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2453 digit borrow = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2454
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2455 /* Ensure a is the larger of the two: */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2456 if (size_a < size_b) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2457 sign = -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2458 { PyLongObject *temp = a; a = b; b = temp; }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2459 { Py_ssize_t size_temp = size_a;
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2460 size_a = size_b;
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2461 size_b = size_temp; }
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2462 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2463 else if (size_a == size_b) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2464 /* Find highest digit where a and b differ: */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2465 i = size_a;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2466 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2467 ;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2468 if (i < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2469 return _PyLong_New(0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2470 if (a->ob_digit[i] < b->ob_digit[i]) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2471 sign = -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2472 { PyLongObject *temp = a; a = b; b = temp; }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2473 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2474 size_a = size_b = i+1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2475 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2476 z = _PyLong_New(size_a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2477 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2478 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2479 for (i = 0; i < size_b; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2480 /* The following assumes unsigned arithmetic
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2481 works module 2**N for some N>PyLong_SHIFT. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2482 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2483 z->ob_digit[i] = borrow & PyLong_MASK;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2484 borrow >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2485 borrow &= 1; /* Keep only one sign bit */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2486 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2487 for (; i < size_a; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2488 borrow = a->ob_digit[i] - borrow;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2489 z->ob_digit[i] = borrow & PyLong_MASK;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2490 borrow >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2491 borrow &= 1; /* Keep only one sign bit */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2492 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2493 assert(borrow == 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2494 if (sign < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2495 z->ob_size = -(z->ob_size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2496 return long_normalize(z);
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2497 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2498
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
2499 static PyObject *
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
2500 long_add(PyLongObject *v, PyLongObject *w)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2501 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2502 PyLongObject *a, *b, *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2503
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2504 CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2505
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2506 if (a->ob_size < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2507 if (b->ob_size < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2508 z = x_add(a, b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2509 if (z != NULL && z->ob_size != 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2510 z->ob_size = -(z->ob_size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2511 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2512 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2513 z = x_sub(b, a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2514 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2515 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2516 if (b->ob_size < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2517 z = x_sub(a, b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2518 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2519 z = x_add(a, b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2520 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2521 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2522 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2523 return (PyObject *)z;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2524 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2525
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
2526 static PyObject *
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
2527 long_sub(PyLongObject *v, PyLongObject *w)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2528 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2529 PyLongObject *a, *b, *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2530
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2531 CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2532
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2533 if (a->ob_size < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2534 if (b->ob_size < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2535 z = x_sub(a, b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2536 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2537 z = x_add(a, b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2538 if (z != NULL && z->ob_size != 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2539 z->ob_size = -(z->ob_size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2540 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2541 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2542 if (b->ob_size < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2543 z = x_add(a, b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2544 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2545 z = x_sub(a, b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2546 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2547 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2548 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2549 return (PyObject *)z;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2550 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2551
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2552 /* Grade school multiplication, ignoring the signs.
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2553 * Returns the absolute value of the product, or NULL if error.
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2554 */
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2555 static PyLongObject *
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2556 x_mul(PyLongObject *a, PyLongObject *b)
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
2557 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2558 PyLongObject *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2559 Py_ssize_t size_a = ABS(Py_SIZE(a));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2560 Py_ssize_t size_b = ABS(Py_SIZE(b));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2561 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2562
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2563 z = _PyLong_New(size_a + size_b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2564 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2565 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2566
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2567 memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2568 if (a == b) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2569 /* Efficient squaring per HAC, Algorithm 14.16:
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2570 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2571 * Gives slightly less than a 2x speedup when a == b,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2572 * via exploiting that each entry in the multiplication
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2573 * pyramid appears twice (except for the size_a squares).
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2574 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2575 for (i = 0; i < size_a; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2576 twodigits carry;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2577 twodigits f = a->ob_digit[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2578 digit *pz = z->ob_digit + (i << 1);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2579 digit *pa = a->ob_digit + i + 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2580 digit *paend = a->ob_digit + size_a;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2581
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2582 SIGCHECK({
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2583 Py_DECREF(z);
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2584 return NULL;
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
2585 });
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2586
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2587 carry = *pz + f * f;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2588 *pz++ = (digit)(carry & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2589 carry >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2590 assert(carry <= PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2591
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2592 /* Now f is added in twice in each column of the
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2593 * pyramid it appears. Same as adding f<<1 once.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2594 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2595 f <<= 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2596 while (pa < paend) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2597 carry += *pz + *pa++ * f;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2598 *pz++ = (digit)(carry & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2599 carry >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2600 assert(carry <= (PyLong_MASK << 1));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2601 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2602 if (carry) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2603 carry += *pz;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2604 *pz++ = (digit)(carry & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2605 carry >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2606 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2607 if (carry)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2608 *pz += (digit)(carry & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2609 assert((carry >> PyLong_SHIFT) == 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2610 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2611 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2612 else { /* a is not the same as b -- gradeschool long mult */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2613 for (i = 0; i < size_a; ++i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2614 twodigits carry = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2615 twodigits f = a->ob_digit[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2616 digit *pz = z->ob_digit + i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2617 digit *pb = b->ob_digit;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2618 digit *pbend = b->ob_digit + size_b;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2619
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2620 SIGCHECK({
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2621 Py_DECREF(z);
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2622 return NULL;
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
2623 });
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2624
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2625 while (pb < pbend) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2626 carry += *pz + *pb++ * f;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2627 *pz++ = (digit)(carry & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2628 carry >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2629 assert(carry <= PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2630 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2631 if (carry)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2632 *pz += (digit)(carry & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2633 assert((carry >> PyLong_SHIFT) == 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2634 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2635 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2636 return long_normalize(z);
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2637 }
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2638
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2639 /* A helper for Karatsuba multiplication (k_mul).
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2640 Takes a long "n" and an integer "size" representing the place to
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2641 split, and sets low and high such that abs(n) == (high << size) + low,
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2642 viewing the shift as being by digits. The sign bit is ignored, and
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2643 the return values are >= 0.
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2644 Returns 0 on success, -1 on failure.
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2645 */
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2646 static int
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2647 kmul_split(PyLongObject *n,
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2648 Py_ssize_t size,
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2649 PyLongObject **high,
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2650 PyLongObject **low)
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2651 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2652 PyLongObject *hi, *lo;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2653 Py_ssize_t size_lo, size_hi;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2654 const Py_ssize_t size_n = ABS(Py_SIZE(n));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2655
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2656 size_lo = MIN(size_n, size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2657 size_hi = size_n - size_lo;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2658
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2659 if ((hi = _PyLong_New(size_hi)) == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2660 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2661 if ((lo = _PyLong_New(size_lo)) == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2662 Py_DECREF(hi);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2663 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2664 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2665
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2666 memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2667 memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2668
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2669 *high = long_normalize(hi);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2670 *low = long_normalize(lo);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2671 return 0;
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2672 }
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2673
24773
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2674 static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b);
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2675
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2676 /* Karatsuba multiplication. Ignores the input signs, and returns the
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2677 * absolute value of the product (or NULL if error).
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2678 * See Knuth Vol. 2 Chapter 4.3.3 (Pp. 294-295).
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2679 */
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2680 static PyLongObject *
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2681 k_mul(PyLongObject *a, PyLongObject *b)
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2682 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2683 Py_ssize_t asize = ABS(Py_SIZE(a));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2684 Py_ssize_t bsize = ABS(Py_SIZE(b));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2685 PyLongObject *ah = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2686 PyLongObject *al = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2687 PyLongObject *bh = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2688 PyLongObject *bl = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2689 PyLongObject *ret = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2690 PyLongObject *t1, *t2, *t3;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2691 Py_ssize_t shift; /* the number of digits we split off */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2692 Py_ssize_t i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2693
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2694 /* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2695 * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh + ah*bh + al*bl
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2696 * Then the original product is
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2697 * ah*bh*X*X + (k - ah*bh - al*bl)*X + al*bl
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2698 * By picking X to be a power of 2, "*X" is just shifting, and it's
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2699 * been reduced to 3 multiplies on numbers half the size.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2700 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2701
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2702 /* We want to split based on the larger number; fiddle so that b
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2703 * is largest.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2704 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2705 if (asize > bsize) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2706 t1 = a;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2707 a = b;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2708 b = t1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2709
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2710 i = asize;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2711 asize = bsize;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2712 bsize = i;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2713 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2714
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2715 /* Use gradeschool math when either number is too small. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2716 i = a == b ? KARATSUBA_SQUARE_CUTOFF : KARATSUBA_CUTOFF;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2717 if (asize <= i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2718 if (asize == 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2719 return _PyLong_New(0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2720 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2721 return x_mul(a, b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2722 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2723
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2724 /* If a is small compared to b, splitting on b gives a degenerate
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2725 * case with ah==0, and Karatsuba may be (even much) less efficient
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2726 * than "grade school" then. However, we can still win, by viewing
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2727 * b as a string of "big digits", each of width a->ob_size. That
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2728 * leads to a sequence of balanced calls to k_mul.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2729 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2730 if (2 * asize <= bsize)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2731 return k_lopsided_mul(a, b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2732
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2733 /* Split a & b into hi & lo pieces. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2734 shift = bsize >> 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2735 if (kmul_split(a, shift, &ah, &al) < 0) goto fail;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2736 assert(Py_SIZE(ah) > 0); /* the split isn't degenerate */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2737
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2738 if (a == b) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2739 bh = ah;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2740 bl = al;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2741 Py_INCREF(bh);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2742 Py_INCREF(bl);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2743 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2744 else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2745
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2746 /* The plan:
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2747 * 1. Allocate result space (asize + bsize digits: that's always
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2748 * enough).
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2749 * 2. Compute ah*bh, and copy into result at 2*shift.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2750 * 3. Compute al*bl, and copy into result at 0. Note that this
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2751 * can't overlap with #2.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2752 * 4. Subtract al*bl from the result, starting at shift. This may
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2753 * underflow (borrow out of the high digit), but we don't care:
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2754 * we're effectively doing unsigned arithmetic mod
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2755 * PyLong_BASE**(sizea + sizeb), and so long as the *final* result fits,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2756 * borrows and carries out of the high digit can be ignored.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2757 * 5. Subtract ah*bh from the result, starting at shift.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2758 * 6. Compute (ah+al)*(bh+bl), and add it into the result starting
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2759 * at shift.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2760 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2761
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2762 /* 1. Allocate result space. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2763 ret = _PyLong_New(asize + bsize);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2764 if (ret == NULL) goto fail;
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2765 #ifdef Py_DEBUG
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2766 /* Fill with trash, to catch reference to uninitialized digits. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2767 memset(ret->ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit));
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2768 #endif
24751
dbf6e563023b x_mul(): This failed to normalize its result.
Tim Peters <tim.peters@gmail.com>
parents: 24750
diff changeset
2769
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2770 /* 2. t1 <- ah*bh, and copy into high digits of result. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2771 if ((t1 = k_mul(ah, bh)) == NULL) goto fail;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2772 assert(Py_SIZE(t1) >= 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2773 assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2774 memcpy(ret->ob_digit + 2*shift, t1->ob_digit,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2775 Py_SIZE(t1) * sizeof(digit));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2776
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2777 /* Zero-out the digits higher than the ah*bh copy. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2778 i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2779 if (i)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2780 memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2781 i * sizeof(digit));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2782
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2783 /* 3. t2 <- al*bl, and copy into the low digits. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2784 if ((t2 = k_mul(al, bl)) == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2785 Py_DECREF(t1);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2786 goto fail;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2787 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2788 assert(Py_SIZE(t2) >= 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2789 assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2790 memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2791
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2792 /* Zero out remaining digits. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2793 i = 2*shift - Py_SIZE(t2); /* number of uninitialized digits */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2794 if (i)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2795 memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2796
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2797 /* 4 & 5. Subtract ah*bh (t1) and al*bl (t2). We do al*bl first
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2798 * because it's fresher in cache.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2799 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2800 i = Py_SIZE(ret) - shift; /* # digits after shift */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2801 (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2802 Py_DECREF(t2);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2803
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2804 (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2805 Py_DECREF(t1);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2806
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2807 /* 6. t3 <- (ah+al)(bh+bl), and add into result. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2808 if ((t1 = x_add(ah, al)) == NULL) goto fail;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2809 Py_DECREF(ah);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2810 Py_DECREF(al);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2811 ah = al = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2812
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2813 if (a == b) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2814 t2 = t1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2815 Py_INCREF(t2);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2816 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2817 else if ((t2 = x_add(bh, bl)) == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2818 Py_DECREF(t1);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2819 goto fail;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2820 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2821 Py_DECREF(bh);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2822 Py_DECREF(bl);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2823 bh = bl = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2824
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2825 t3 = k_mul(t1, t2);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2826 Py_DECREF(t1);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2827 Py_DECREF(t2);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2828 if (t3 == NULL) goto fail;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2829 assert(Py_SIZE(t3) >= 0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2830
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2831 /* Add t3. It's not obvious why we can't run out of room here.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2832 * See the (*) comment after this function.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2833 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2834 (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2835 Py_DECREF(t3);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2836
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2837 return long_normalize(ret);
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2838
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2839 fail:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2840 Py_XDECREF(ret);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2841 Py_XDECREF(ah);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2842 Py_XDECREF(al);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2843 Py_XDECREF(bh);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2844 Py_XDECREF(bl);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2845 return NULL;
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2846 }
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2847
24791
dbf4cc560898 k_mul(): The fix for (ah+al)*(bh+bl) spilling 1 bit beyond the allocated
Tim Peters <tim.peters@gmail.com>
parents: 24777
diff changeset
2848 /* (*) Why adding t3 can't "run out of room" above.
dbf4cc560898 k_mul(): The fix for (ah+al)*(bh+bl) spilling 1 bit beyond the allocated
Tim Peters <tim.peters@gmail.com>
parents: 24777
diff changeset
2849
24846
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2850 Let f(x) mean the floor of x and c(x) mean the ceiling of x. Some facts
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2851 to start with:
24791
dbf4cc560898 k_mul(): The fix for (ah+al)*(bh+bl) spilling 1 bit beyond the allocated
Tim Peters <tim.peters@gmail.com>
parents: 24777
diff changeset
2852
24846
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2853 1. For any integer i, i = c(i/2) + f(i/2). In particular,
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2854 bsize = c(bsize/2) + f(bsize/2).
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2855 2. shift = f(bsize/2)
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2856 3. asize <= bsize
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2857 4. Since we call k_lopsided_mul if asize*2 <= bsize, asize*2 > bsize in this
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2858 routine, so asize > bsize/2 >= f(bsize/2) in this routine.
24791
dbf4cc560898 k_mul(): The fix for (ah+al)*(bh+bl) spilling 1 bit beyond the allocated
Tim Peters <tim.peters@gmail.com>
parents: 24777
diff changeset
2859
24846
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2860 We allocated asize + bsize result digits, and add t3 into them at an offset
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2861 of shift. This leaves asize+bsize-shift allocated digit positions for t3
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2862 to fit into, = (by #1 and #2) asize + f(bsize/2) + c(bsize/2) - f(bsize/2) =
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2863 asize + c(bsize/2) available digit positions.
24791
dbf4cc560898 k_mul(): The fix for (ah+al)*(bh+bl) spilling 1 bit beyond the allocated
Tim Peters <tim.peters@gmail.com>
parents: 24777
diff changeset
2864
24846
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2865 bh has c(bsize/2) digits, and bl at most f(size/2) digits. So bh+hl has
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2866 at most c(bsize/2) digits + 1 bit.
24791
dbf4cc560898 k_mul(): The fix for (ah+al)*(bh+bl) spilling 1 bit beyond the allocated
Tim Peters <tim.peters@gmail.com>
parents: 24777
diff changeset
2867
24846
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2868 If asize == bsize, ah has c(bsize/2) digits, else ah has at most f(bsize/2)
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2869 digits, and al has at most f(bsize/2) digits in any case. So ah+al has at
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2870 most (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 1 bit.
24791
dbf4cc560898 k_mul(): The fix for (ah+al)*(bh+bl) spilling 1 bit beyond the allocated
Tim Peters <tim.peters@gmail.com>
parents: 24777
diff changeset
2871
24846
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2872 The product (ah+al)*(bh+bl) therefore has at most
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2873
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2874 c(bsize/2) + (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits
24791
dbf4cc560898 k_mul(): The fix for (ah+al)*(bh+bl) spilling 1 bit beyond the allocated
Tim Peters <tim.peters@gmail.com>
parents: 24777
diff changeset
2875
24846
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2876 and we have asize + c(bsize/2) available digit positions. We need to show
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2877 this is always enough. An instance of c(bsize/2) cancels out in both, so
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2878 the question reduces to whether asize digits is enough to hold
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2879 (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits. If asize < bsize,
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2880 then we're asking whether asize digits >= f(bsize/2) digits + 2 bits. By #4,
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2881 asize is at least f(bsize/2)+1 digits, so this in turn reduces to whether 1
44945
bbc719a8b58b Backport of several functions from Python 3.0 to 2.6 including PyUnicode_FromString, PyUnicode_Format and PyLong_From/AsSsize_t. The functions are partly required for the backport of the bytearray type and _fileio module. They should also make it easier to port C to 3.0.
Christian Heimes <christian@cheimes.de>
parents: 44749
diff changeset
2882 digit is enough to hold 2 bits. This is so since PyLong_SHIFT=15 >= 2. If
24846
10a4ec45549d k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents: 24845
diff changeset
2883 asize == bsize, then we're asking whether bsize digits is enough to hold
24847
873f12f68e3b Illustrating by example one good reason not to trust a proof <wink>.
Tim Peters <tim.peters@gmail.com>
parents: 24846
diff changeset
2884 c(bsize/2) digits + 2 bits, or equivalently (by #1) whether f(bsize/2) digits
873f12f68e3b Illustrating by example one good reason not to trust a proof <wink>.
Tim Peters <tim.peters@gmail.com>
parents: 24846
diff changeset
2885 is enough to hold 2 bits. This is so if bsize >= 2, which holds because
873f12f68e3b Illustrating by example one good reason not to trust a proof <wink>.
Tim Peters <tim.peters@gmail.com>
parents: 24846
diff changeset
2886 bsize >= KARATSUBA_CUTOFF >= 2.
24821
ae9c9f90b4b0 k_mul() comments: Explained why there's always enough room to subtract
Tim Peters <tim.peters@gmail.com>
parents: 24792
diff changeset
2887
24824
7c91d303c563 k_mul() comments: Simplified the simplified explanation of why ah*bh and
Tim Peters <tim.peters@gmail.com>
parents: 24821
diff changeset
2888 Note that since there's always enough room for (ah+al)*(bh+bl), and that's
7c91d303c563 k_mul() comments: Simplified the simplified explanation of why ah*bh and
Tim Peters <tim.peters@gmail.com>
parents: 24821
diff changeset
2889 clearly >= each of ah*bh and al*bl, there's always enough room to subtract
7c91d303c563 k_mul() comments: Simplified the simplified explanation of why ah*bh and
Tim Peters <tim.peters@gmail.com>
parents: 24821
diff changeset
2890 ah*bh and al*bl too.
24791
dbf4cc560898 k_mul(): The fix for (ah+al)*(bh+bl) spilling 1 bit beyond the allocated
Tim Peters <tim.peters@gmail.com>
parents: 24777
diff changeset
2891 */
dbf4cc560898 k_mul(): The fix for (ah+al)*(bh+bl) spilling 1 bit beyond the allocated
Tim Peters <tim.peters@gmail.com>
parents: 24777
diff changeset
2892
24773
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2893 /* b has at least twice the digits of a, and a is big enough that Karatsuba
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2894 * would pay off *if* the inputs had balanced sizes. View b as a sequence
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2895 * of slices, each with a->ob_size digits, and multiply the slices by a,
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2896 * one at a time. This gives k_mul balanced inputs to work with, and is
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2897 * also cache-friendly (we compute one double-width slice of the result
68503
ee5350f1d0c2 #11515: fix several typos. Patch by Piotr Kasprzyk.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 68256
diff changeset
2898 * at a time, then move on, never backtracking except for the helpful
24773
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2899 * single-width slice overlap between successive partial sums).
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2900 */
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2901 static PyLongObject *
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2902 k_lopsided_mul(PyLongObject *a, PyLongObject *b)
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2903 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2904 const Py_ssize_t asize = ABS(Py_SIZE(a));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2905 Py_ssize_t bsize = ABS(Py_SIZE(b));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2906 Py_ssize_t nbdone; /* # of b digits already multiplied */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2907 PyLongObject *ret;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2908 PyLongObject *bslice = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2909
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2910 assert(asize > KARATSUBA_CUTOFF);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2911 assert(2 * asize <= bsize);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2912
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2913 /* Allocate result space, and zero it out. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2914 ret = _PyLong_New(asize + bsize);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2915 if (ret == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2916 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2917 memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2918
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2919 /* Successive slices of b are copied into bslice. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2920 bslice = _PyLong_New(asize);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2921 if (bslice == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2922 goto fail;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2923
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2924 nbdone = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2925 while (bsize > 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2926 PyLongObject *product;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2927 const Py_ssize_t nbtouse = MIN(bsize, asize);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2928
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2929 /* Multiply the next slice of b by a. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2930 memcpy(bslice->ob_digit, b->ob_digit + nbdone,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2931 nbtouse * sizeof(digit));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2932 Py_SIZE(bslice) = nbtouse;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2933 product = k_mul(a, bslice);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2934 if (product == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2935 goto fail;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2936
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2937 /* Add into result. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2938 (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2939 product->ob_digit, Py_SIZE(product));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2940 Py_DECREF(product);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2941
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2942 bsize -= nbtouse;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2943 nbdone += nbtouse;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2944 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2945
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2946 Py_DECREF(bslice);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2947 return long_normalize(ret);
24773
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2948
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
2949 fail:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2950 Py_DECREF(ret);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2951 Py_XDECREF(bslice);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2952 return NULL;
24773
801a44ab2aae Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents: 24765
diff changeset
2953 }
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2954
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2955 static PyObject *
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2956 long_mul(PyLongObject *v, PyLongObject *w)
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2957 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2958 PyLongObject *a, *b, *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2959
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2960 if (!convert_binop((PyObject *)v, (PyObject *)w, &a, &b)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2961 Py_INCREF(Py_NotImplemented);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2962 return Py_NotImplemented;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2963 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2964
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2965 z = k_mul(a, b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2966 /* Negate if exactly one of the inputs is negative. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2967 if (((a->ob_size ^ b->ob_size) < 0) && z)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2968 z->ob_size = -(z->ob_size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2969 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2970 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2971 return (PyObject *)z;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2972 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2973
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
2974 /* The / and % operators are now defined in terms of divmod().
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
2975 The expression a mod b has the value a - b*floor(a/b).
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
2976 The long_divrem function gives the remainder after division of
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2977 |a| by |b|, with the sign of a. This is also expressed
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2978 as a - b*trunc(a/b), if trunc truncates towards zero.
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2979 Some examples:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2980 a b a rem b a mod b
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2981 13 10 3 3
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2982 -13 10 -3 7
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2983 13 -10 3 -7
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2984 -13 -10 -3 -3
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2985 So, to get from rem to mod, we have to add b if a and b
242
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
2986 have different signs. We then subtract one from the 'div'
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
2987 part of the outcome to keep the invariant intact. */
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2988
33327
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
2989 /* Compute
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
2990 * *pdiv, *pmod = divmod(v, w)
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
2991 * NULL can be passed for pdiv or pmod, in which case that part of
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
2992 * the result is simply thrown away. The caller owns a reference to
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
2993 * each of these it requests (does not pass NULL for).
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
2994 */
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
2995 static int
24745
ba035f4b47c1 Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents: 24280
diff changeset
2996 l_divmod(PyLongObject *v, PyLongObject *w,
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2997 PyLongObject **pdiv, PyLongObject **pmod)
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
2998 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
2999 PyLongObject *div, *mod;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3000
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3001 if (long_divrem(v, w, &div, &mod) < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3002 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3003 if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) ||
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3004 (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3005 PyLongObject *temp;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3006 PyLongObject *one;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3007 temp = (PyLongObject *) long_add(mod, w);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3008 Py_DECREF(mod);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3009 mod = temp;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3010 if (mod == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3011 Py_DECREF(div);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3012 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3013 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3014 one = (PyLongObject *) PyLong_FromLong(1L);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3015 if (one == NULL ||
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3016 (temp = (PyLongObject *) long_sub(div, one)) == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3017 Py_DECREF(mod);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3018 Py_DECREF(div);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3019 Py_XDECREF(one);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3020 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3021 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3022 Py_DECREF(one);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3023 Py_DECREF(div);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3024 div = temp;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3025 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3026 if (pdiv != NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3027 *pdiv = div;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3028 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3029 Py_DECREF(div);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3030
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3031 if (pmod != NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3032 *pmod = mod;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3033 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3034 Py_DECREF(mod);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3035
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3036 return 0;
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3037 }
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3038
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3039 static PyObject *
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
3040 long_div(PyObject *v, PyObject *w)
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3041 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3042 PyLongObject *a, *b, *div;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3043
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3044 CONVERT_BINOP(v, w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3045 if (l_divmod(a, b, &div, NULL) < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3046 div = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3047 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3048 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3049 return (PyObject *)div;
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3050 }
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3051
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3052 static PyObject *
19633
c0a44829bcd5 Add warning mode for classic division, almost exactly as specified in
Guido van Rossum <guido@python.org>
parents: 19610
diff changeset
3053 long_classic_div(PyObject *v, PyObject *w)
c0a44829bcd5 Add warning mode for classic division, almost exactly as specified in
Guido van Rossum <guido@python.org>
parents: 19610
diff changeset
3054 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3055 PyLongObject *a, *b, *div;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3056
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3057 CONVERT_BINOP(v, w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3058 if (Py_DivisionWarningFlag &&
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3059 PyErr_Warn(PyExc_DeprecationWarning, "classic long division") < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3060 div = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3061 else if (l_divmod(a, b, &div, NULL) < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3062 div = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3063 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3064 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3065 return (PyObject *)div;
19633
c0a44829bcd5 Add warning mode for classic division, almost exactly as specified in
Guido van Rossum <guido@python.org>
parents: 19610
diff changeset
3066 }
c0a44829bcd5 Add warning mode for classic division, almost exactly as specified in
Guido van Rossum <guido@python.org>
parents: 19610
diff changeset
3067
57941
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3068 /* PyLong/PyLong -> float, with correctly rounded result. */
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3069
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3070 #define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT)
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3071 #define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT)
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3072
19633
c0a44829bcd5 Add warning mode for classic division, almost exactly as specified in
Guido van Rossum <guido@python.org>
parents: 19610
diff changeset
3073 static PyObject *
19675
685dcae5c123 Move long_true_divide next to the other division routines (for clarity!).
Tim Peters <tim.peters@gmail.com>
parents: 19674
diff changeset
3074 long_true_divide(PyObject *v, PyObject *w)
685dcae5c123 Move long_true_divide next to the other division routines (for clarity!).
Tim Peters <tim.peters@gmail.com>
parents: 19674
diff changeset
3075 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3076 PyLongObject *a, *b, *x;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3077 Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3078 digit mask, low;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3079 int inexact, negate, a_is_small, b_is_small;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3080 double dx, result;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3081
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3082 CONVERT_BINOP(v, w, &a, &b);
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3083
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3084 /*
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3085 Method in a nutshell:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3086
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3087 0. reduce to case a, b > 0; filter out obvious underflow/overflow
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3088 1. choose a suitable integer 'shift'
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3089 2. use integer arithmetic to compute x = floor(2**-shift*a/b)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3090 3. adjust x for correct rounding
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3091 4. convert x to a double dx with the same value
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3092 5. return ldexp(dx, shift).
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3093
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3094 In more detail:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3095
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3096 0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3097 returns either 0.0 or -0.0, depending on the sign of b. For a and
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3098 b both nonzero, ignore signs of a and b, and add the sign back in
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3099 at the end. Now write a_bits and b_bits for the bit lengths of a
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3100 and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3101 for b). Then
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3102
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3103 2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1).
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3104
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3105 So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3106 so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP -
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3107 DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3108 the way, we can assume that
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3109
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3110 DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP.
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3111
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3112 1. The integer 'shift' is chosen so that x has the right number of
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3113 bits for a double, plus two or three extra bits that will be used
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3114 in the rounding decisions. Writing a_bits and b_bits for the
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3115 number of significant bits in a and b respectively, a
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3116 straightforward formula for shift is:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3117
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3118 shift = a_bits - b_bits - DBL_MANT_DIG - 2
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3119
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3120 This is fine in the usual case, but if a/b is smaller than the
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3121 smallest normal float then it can lead to double rounding on an
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3122 IEEE 754 platform, giving incorrectly rounded results. So we
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3123 adjust the formula slightly. The actual formula used is:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3124
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3125 shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3126
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3127 2. The quantity x is computed by first shifting a (left -shift bits
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3128 if shift <= 0, right shift bits if shift > 0) and then dividing by
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3129 b. For both the shift and the division, we keep track of whether
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3130 the result is inexact, in a flag 'inexact'; this information is
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3131 needed at the rounding stage.
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3132
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3133 With the choice of shift above, together with our assumption that
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3134 a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3135 that x >= 1.
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3136
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3137 3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3138 this with an exactly representable float of the form
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3139
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3140 round(x/2**extra_bits) * 2**(extra_bits+shift).
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3141
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3142 For float representability, we need x/2**extra_bits <
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3143 2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP -
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3144 DBL_MANT_DIG. This translates to the condition:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3145
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3146 extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3147
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3148 To round, we just modify the bottom digit of x in-place; this can
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3149 end up giving a digit with value > PyLONG_MASK, but that's not a
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3150 problem since digits can hold values up to 2*PyLONG_MASK+1.
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3151
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3152 With the original choices for shift above, extra_bits will always
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3153 be 2 or 3. Then rounding under the round-half-to-even rule, we
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3154 round up iff the most significant of the extra bits is 1, and
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3155 either: (a) the computation of x in step 2 had an inexact result,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3156 or (b) at least one other of the extra bits is 1, or (c) the least
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3157 significant bit of x (above those to be rounded) is 1.
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3158
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3159 4. Conversion to a double is straightforward; all floating-point
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3160 operations involved in the conversion are exact, so there's no
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3161 danger of rounding errors.
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3162
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3163 5. Use ldexp(x, shift) to compute x*2**shift, the final result.
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3164 The result will always be exactly representable as a double, except
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3165 in the case that it overflows. To avoid dependence on the exact
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3166 behaviour of ldexp on overflow, we check for overflow before
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3167 applying ldexp. The result of ldexp is adjusted for sign before
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3168 returning.
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3169 */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3170
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3171 /* Reduce to case where a and b are both positive. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3172 a_size = ABS(Py_SIZE(a));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3173 b_size = ABS(Py_SIZE(b));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3174 negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3175 if (b_size == 0) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3176 PyErr_SetString(PyExc_ZeroDivisionError,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3177 "division by zero");
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3178 goto error;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3179 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3180 if (a_size == 0)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3181 goto underflow_or_zero;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3182
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3183 /* Fast path for a and b small (exactly representable in a double).
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3184 Relies on floating-point division being correctly rounded; results
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3185 may be subject to double rounding on x86 machines that operate with
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3186 the x87 FPU set to 64-bit precision. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3187 a_is_small = a_size <= MANT_DIG_DIGITS ||
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3188 (a_size == MANT_DIG_DIGITS+1 &&
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3189 a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3190 b_is_small = b_size <= MANT_DIG_DIGITS ||
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3191 (b_size == MANT_DIG_DIGITS+1 &&
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3192 b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3193 if (a_is_small && b_is_small) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3194 double da, db;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3195 da = a->ob_digit[--a_size];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3196 while (a_size > 0)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3197 da = da * PyLong_BASE + a->ob_digit[--a_size];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3198 db = b->ob_digit[--b_size];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3199 while (b_size > 0)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3200 db = db * PyLong_BASE + b->ob_digit[--b_size];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3201 result = da / db;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3202 goto success;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3203 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3204
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3205 /* Catch obvious cases of underflow and overflow */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3206 diff = a_size - b_size;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3207 if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3208 /* Extreme overflow */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3209 goto overflow;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3210 else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3211 /* Extreme underflow */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3212 goto underflow_or_zero;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3213 /* Next line is now safe from overflowing a Py_ssize_t */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3214 diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) -
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3215 bits_in_digit(b->ob_digit[b_size - 1]);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3216 /* Now diff = a_bits - b_bits. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3217 if (diff > DBL_MAX_EXP)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3218 goto overflow;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3219 else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3220 goto underflow_or_zero;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3221
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3222 /* Choose value for shift; see comments for step 1 above. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3223 shift = MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3224
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3225 inexact = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3226
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3227 /* x = abs(a * 2**-shift) */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3228 if (shift <= 0) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3229 Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3230 digit rem;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3231 /* x = a << -shift */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3232 if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3233 /* In practice, it's probably impossible to end up
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3234 here. Both a and b would have to be enormous,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3235 using close to SIZE_T_MAX bytes of memory each. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3236 PyErr_SetString(PyExc_OverflowError,
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3237 "intermediate overflow during division");
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3238 goto error;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3239 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3240 x = _PyLong_New(a_size + shift_digits + 1);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3241 if (x == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3242 goto error;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3243 for (i = 0; i < shift_digits; i++)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3244 x->ob_digit[i] = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3245 rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3246 a_size, -shift % PyLong_SHIFT);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3247 x->ob_digit[a_size + shift_digits] = rem;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3248 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3249 else {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3250 Py_ssize_t shift_digits = shift / PyLong_SHIFT;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3251 digit rem;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3252 /* x = a >> shift */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3253 assert(a_size >= shift_digits);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3254 x = _PyLong_New(a_size - shift_digits);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3255 if (x == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3256 goto error;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3257 rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3258 a_size - shift_digits, shift % PyLong_SHIFT);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3259 /* set inexact if any of the bits shifted out is nonzero */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3260 if (rem)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3261 inexact = 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3262 while (!inexact && shift_digits > 0)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3263 if (a->ob_digit[--shift_digits])
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3264 inexact = 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3265 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3266 long_normalize(x);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3267 x_size = Py_SIZE(x);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3268
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3269 /* x //= b. If the remainder is nonzero, set inexact. We own the only
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3270 reference to x, so it's safe to modify it in-place. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3271 if (b_size == 1) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3272 digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3273 b->ob_digit[0]);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3274 long_normalize(x);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3275 if (rem)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3276 inexact = 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3277 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3278 else {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3279 PyLongObject *div, *rem;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3280 div = x_divrem(x, b, &rem);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3281 Py_DECREF(x);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3282 x = div;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3283 if (x == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3284 goto error;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3285 if (Py_SIZE(rem))
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3286 inexact = 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3287 Py_DECREF(rem);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3288 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3289 x_size = ABS(Py_SIZE(x));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3290 assert(x_size > 0); /* result of division is never zero */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3291 x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3292
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3293 /* The number of extra bits that have to be rounded away. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3294 extra_bits = MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3295 assert(extra_bits == 2 || extra_bits == 3);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3296
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3297 /* Round by directly modifying the low digit of x. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3298 mask = (digit)1 << (extra_bits - 1);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3299 low = x->ob_digit[0] | inexact;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3300 if (low & mask && low & (3*mask-1))
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3301 low += mask;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3302 x->ob_digit[0] = low & ~(mask-1U);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3303
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3304 /* Convert x to a double dx; the conversion is exact. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3305 dx = x->ob_digit[--x_size];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3306 while (x_size > 0)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3307 dx = dx * PyLong_BASE + x->ob_digit[--x_size];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3308 Py_DECREF(x);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3309
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3310 /* Check whether ldexp result will overflow a double. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3311 if (shift + x_bits >= DBL_MAX_EXP &&
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3312 (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, (int)x_bits)))
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3313 goto overflow;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3314 result = ldexp(dx, (int)shift);
57941
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3315
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3316 success:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3317 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3318 Py_DECREF(b);
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3319 return PyFloat_FromDouble(negate ? -result : result);
57941
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3320
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3321 underflow_or_zero:
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3322 Py_DECREF(a);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3323 Py_DECREF(b);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3324 return PyFloat_FromDouble(negate ? -0.0 : 0.0);
57941
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3325
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3326 overflow:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3327 PyErr_SetString(PyExc_OverflowError,
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3328 "integer division result too large for a float");
57941
c4e60988834d Issue #1811: Improve accuracy and consistency of true division for integers.
Mark Dickinson <dickinsm@gmail.com>
parents: 57851
diff changeset
3329 error:
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3330 Py_DECREF(a);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3331 Py_DECREF(b);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3332 return NULL;
19675
685dcae5c123 Move long_true_divide next to the other division routines (for clarity!).
Tim Peters <tim.peters@gmail.com>
parents: 19674
diff changeset
3333 }
685dcae5c123 Move long_true_divide next to the other division routines (for clarity!).
Tim Peters <tim.peters@gmail.com>
parents: 19674
diff changeset
3334
685dcae5c123 Move long_true_divide next to the other division routines (for clarity!).
Tim Peters <tim.peters@gmail.com>
parents: 19674
diff changeset
3335 static PyObject *
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
3336 long_mod(PyObject *v, PyObject *w)
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3337 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3338 PyLongObject *a, *b, *mod;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3339
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3340 CONVERT_BINOP(v, w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3341
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3342 if (l_divmod(a, b, NULL, &mod) < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3343 mod = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3344 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3345 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3346 return (PyObject *)mod;
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3347 }
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3348
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3349 static PyObject *
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
3350 long_divmod(PyObject *v, PyObject *w)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3351 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3352 PyLongObject *a, *b, *div, *mod;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3353 PyObject *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3354
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3355 CONVERT_BINOP(v, w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3356
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3357 if (l_divmod(a, b, &div, &mod) < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3358 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3359 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3360 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3361 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3362 z = PyTuple_New(2);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3363 if (z != NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3364 PyTuple_SetItem(z, 0, (PyObject *) div);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3365 PyTuple_SetItem(z, 1, (PyObject *) mod);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3366 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3367 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3368 Py_DECREF(div);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3369 Py_DECREF(mod);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3370 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3371 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3372 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3373 return z;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3374 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3375
33327
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
3376 /* pow(v, w, x) */
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3377 static PyObject *
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
3378 long_pow(PyObject *v, PyObject *w, PyObject *x)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3379 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3380 PyLongObject *a, *b, *c; /* a,b,c = v,w,x */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3381 int negativeOutput = 0; /* if x<0 return negative output */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3382
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3383 PyLongObject *z = NULL; /* accumulated result */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3384 Py_ssize_t i, j, k; /* counters */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3385 PyLongObject *temp = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3386
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3387 /* 5-ary values. If the exponent is large enough, table is
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3388 * precomputed so that table[i] == a**i % c for i in range(32).
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3389 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3390 PyLongObject *table[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3391 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3392
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3393 /* a, b, c = v, w, x */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3394 CONVERT_BINOP(v, w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3395 if (PyLong_Check(x)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3396 c = (PyLongObject *)x;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3397 Py_INCREF(x);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3398 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3399 else if (PyInt_Check(x)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3400 c = (PyLongObject *)PyLong_FromLong(PyInt_AS_LONG(x));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3401 if (c == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3402 goto Error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3403 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3404 else if (x == Py_None)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3405 c = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3406 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3407 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3408 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3409 Py_INCREF(Py_NotImplemented);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3410 return Py_NotImplemented;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3411 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3412
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3413 if (Py_SIZE(b) < 0) { /* if exponent is negative */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3414 if (c) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3415 PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3416 "cannot be negative when 3rd argument specified");
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3417 goto Error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3418 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3419 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3420 /* else return a float. This works because we know
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3421 that this calls float_pow() which converts its
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3422 arguments to double. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3423 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3424 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3425 return PyFloat_Type.tp_as_number->nb_power(v, w, x);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3426 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3427 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3428
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3429 if (c) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3430 /* if modulus == 0:
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3431 raise ValueError() */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3432 if (Py_SIZE(c) == 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3433 PyErr_SetString(PyExc_ValueError,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3434 "pow() 3rd argument cannot be 0");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3435 goto Error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3436 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3437
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3438 /* if modulus < 0:
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3439 negativeOutput = True
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3440 modulus = -modulus */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3441 if (Py_SIZE(c) < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3442 negativeOutput = 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3443 temp = (PyLongObject *)_PyLong_Copy(c);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3444 if (temp == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3445 goto Error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3446 Py_DECREF(c);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3447 c = temp;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3448 temp = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3449 c->ob_size = - c->ob_size;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3450 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3451
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3452 /* if modulus == 1:
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3453 return 0 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3454 if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3455 z = (PyLongObject *)PyLong_FromLong(0L);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3456 goto Done;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3457 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3458
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3459 /* if base < 0:
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3460 base = base % modulus
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3461 Having the base positive just makes things easier. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3462 if (Py_SIZE(a) < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3463 if (l_divmod(a, c, NULL, &temp) < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3464 goto Error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3465 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3466 a = temp;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3467 temp = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3468 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3469 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3470
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3471 /* At this point a, b, and c are guaranteed non-negative UNLESS
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3472 c is NULL, in which case a may be negative. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3473
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3474 z = (PyLongObject *)PyLong_FromLong(1L);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3475 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3476 goto Error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3477
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3478 /* Perform a modular reduction, X = X % c, but leave X alone if c
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3479 * is NULL.
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3480 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3481 #define REDUCE(X) \
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3482 do { \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3483 if (c != NULL) { \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3484 if (l_divmod(X, c, NULL, &temp) < 0) \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3485 goto Error; \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3486 Py_XDECREF(X); \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3487 X = temp; \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3488 temp = NULL; \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3489 } \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3490 } while(0)
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3491
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3492 /* Multiply two values, then reduce the result:
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3493 result = X*Y % c. If c is NULL, skip the mod. */
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3494 #define MULT(X, Y, result) \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3495 do { \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3496 temp = (PyLongObject *)long_mul(X, Y); \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3497 if (temp == NULL) \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3498 goto Error; \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3499 Py_XDECREF(result); \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3500 result = temp; \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3501 temp = NULL; \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3502 REDUCE(result); \
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3503 } while(0)
33327
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
3504
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3505 if (Py_SIZE(b) <= FIVEARY_CUTOFF) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3506 /* Left-to-right binary exponentiation (HAC Algorithm 14.79) */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3507 /* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3508 for (i = Py_SIZE(b) - 1; i >= 0; --i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3509 digit bi = b->ob_digit[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3510
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3511 for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) {
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3512 MULT(z, z, z);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3513 if (bi & j)
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3514 MULT(z, a, z);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3515 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3516 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3517 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3518 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3519 /* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3520 Py_INCREF(z); /* still holds 1L */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3521 table[0] = z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3522 for (i = 1; i < 32; ++i)
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3523 MULT(table[i-1], a, table[i]);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3524
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3525 for (i = Py_SIZE(b) - 1; i >= 0; --i) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3526 const digit bi = b->ob_digit[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3527
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3528 for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3529 const int index = (bi >> j) & 0x1f;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3530 for (k = 0; k < 5; ++k)
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3531 MULT(z, z, z);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3532 if (index)
61470
5cad10b277a4 Wrap multiline macros in a 'do {} while(0)', for safety.
Mark Dickinson <dickinsm@gmail.com>
parents: 61469
diff changeset
3533 MULT(z, table[index], z);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3534 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3535 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3536 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3537
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3538 if (negativeOutput && (Py_SIZE(z) != 0)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3539 temp = (PyLongObject *)long_sub(z, c);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3540 if (temp == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3541 goto Error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3542 Py_DECREF(z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3543 z = temp;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3544 temp = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3545 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3546 goto Done;
33327
5452d4ecddd0 SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents: 33325
diff changeset
3547
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3548 Error:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3549 if (z != NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3550 Py_DECREF(z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3551 z = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3552 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3553 /* fall through */
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3554 Done:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3555 if (Py_SIZE(b) > FIVEARY_CUTOFF) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3556 for (i = 0; i < 32; ++i)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3557 Py_XDECREF(table[i]);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3558 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3559 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3560 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3561 Py_XDECREF(c);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3562 Py_XDECREF(temp);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3563 return (PyObject *)z;
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3564 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3565
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3566 static PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
3567 long_invert(PyLongObject *v)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3568 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3569 /* Implement ~x as -(x+1) */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3570 PyLongObject *x;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3571 PyLongObject *w;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3572 w = (PyLongObject *)PyLong_FromLong(1L);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3573 if (w == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3574 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3575 x = (PyLongObject *) long_add(v, w);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3576 Py_DECREF(w);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3577 if (x == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3578 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3579 Py_SIZE(x) = -(Py_SIZE(x));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3580 return (PyObject *)x;
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3581 }
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3582
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3583 static PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
3584 long_neg(PyLongObject *v)
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3585 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3586 PyLongObject *z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3587 if (v->ob_size == 0 && PyLong_CheckExact(v)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3588 /* -0 == 0 */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3589 Py_INCREF(v);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3590 return (PyObject *) v;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3591 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3592 z = (PyLongObject *)_PyLong_Copy(v);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3593 if (z != NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3594 z->ob_size = -(v->ob_size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3595 return (PyObject *)z;
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3596 }
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3597
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3598 static PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
3599 long_abs(PyLongObject *v)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3600 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3601 if (v->ob_size < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3602 return long_neg(v);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3603 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3604 return long_long((PyObject *)v);
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3605 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3606
242
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
3607 static int
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
3608 long_nonzero(PyLongObject *v)
242
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
3609 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3610 return Py_SIZE(v) != 0;
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3611 }
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3612
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3613 static PyObject *
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
3614 long_rshift(PyLongObject *v, PyLongObject *w)
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3615 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3616 PyLongObject *a, *b;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3617 PyLongObject *z = NULL;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3618 Py_ssize_t shiftby, newsize, wordshift, loshift, hishift, i, j;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3619 digit lomask, himask;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3620
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3621 CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3622
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3623 if (Py_SIZE(a) < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3624 /* Right shifting negative numbers is harder */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3625 PyLongObject *a1, *a2;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3626 a1 = (PyLongObject *) long_invert(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3627 if (a1 == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3628 goto rshift_error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3629 a2 = (PyLongObject *) long_rshift(a1, b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3630 Py_DECREF(a1);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3631 if (a2 == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3632 goto rshift_error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3633 z = (PyLongObject *) long_invert(a2);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3634 Py_DECREF(a2);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3635 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3636 else {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3637 shiftby = PyLong_AsSsize_t((PyObject *)b);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3638 if (shiftby == -1L && PyErr_Occurred())
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3639 goto rshift_error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3640 if (shiftby < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3641 PyErr_SetString(PyExc_ValueError,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3642 "negative shift count");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3643 goto rshift_error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3644 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3645 wordshift = shiftby / PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3646 newsize = ABS(Py_SIZE(a)) - wordshift;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3647 if (newsize <= 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3648 z = _PyLong_New(0);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3649 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3650 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3651 return (PyObject *)z;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3652 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3653 loshift = shiftby % PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3654 hishift = PyLong_SHIFT - loshift;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3655 lomask = ((digit)1 << hishift) - 1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3656 himask = PyLong_MASK ^ lomask;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3657 z = _PyLong_New(newsize);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3658 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3659 goto rshift_error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3660 if (Py_SIZE(a) < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3661 Py_SIZE(z) = -(Py_SIZE(z));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3662 for (i = 0, j = wordshift; i < newsize; i++, j++) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3663 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3664 if (i+1 < newsize)
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3665 z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3666 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3667 z = long_normalize(z);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3668 }
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3669 rshift_error:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3670 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3671 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3672 return (PyObject *) z;
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
3673
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3674 }
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3675
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3676 static PyObject *
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
3677 long_lshift(PyObject *v, PyObject *w)
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3678 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3679 /* This version due to Tim Peters */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3680 PyLongObject *a, *b;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3681 PyLongObject *z = NULL;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3682 Py_ssize_t shiftby, oldsize, newsize, wordshift, remshift, i, j;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3683 twodigits accum;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3684
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3685 CONVERT_BINOP(v, w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3686
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3687 shiftby = PyLong_AsSsize_t((PyObject *)b);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3688 if (shiftby == -1L && PyErr_Occurred())
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3689 goto lshift_error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3690 if (shiftby < 0) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3691 PyErr_SetString(PyExc_ValueError, "negative shift count");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3692 goto lshift_error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3693 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3694 /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3695 wordshift = shiftby / PyLong_SHIFT;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3696 remshift = shiftby - wordshift * PyLong_SHIFT;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3697
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3698 oldsize = ABS(a->ob_size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3699 newsize = oldsize + wordshift;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3700 if (remshift)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3701 ++newsize;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3702 z = _PyLong_New(newsize);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3703 if (z == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3704 goto lshift_error;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3705 if (a->ob_size < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3706 z->ob_size = -(z->ob_size);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3707 for (i = 0; i < wordshift; i++)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3708 z->ob_digit[i] = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3709 accum = 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3710 for (i = wordshift, j = 0; j < oldsize; i++, j++) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3711 accum |= (twodigits)a->ob_digit[j] << remshift;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3712 z->ob_digit[i] = (digit)(accum & PyLong_MASK);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3713 accum >>= PyLong_SHIFT;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3714 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3715 if (remshift)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3716 z->ob_digit[newsize-1] = (digit)accum;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3717 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3718 assert(!accum);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3719 z = long_normalize(z);
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3720 lshift_error:
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3721 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3722 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3723 return (PyObject *) z;
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3724 }
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3725
56733
fbe6b265bd1a Issue #1087418: Small performance boost for bitwise operations on longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 56261
diff changeset
3726 /* Compute two's complement of digit vector a[0:m], writing result to
fbe6b265bd1a Issue #1087418: Small performance boost for bitwise operations on longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 56261
diff changeset
3727 z[0:m]. The digit vector a need not be normalized, but should not
fbe6b265bd1a Issue #1087418: Small performance boost for bitwise operations on longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 56261
diff changeset
3728 be entirely zero. a and z may point to the same digit vector. */
fbe6b265bd1a Issue #1087418: Small performance boost for bitwise operations on longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 56261
diff changeset
3729
fbe6b265bd1a Issue #1087418: Small performance boost for bitwise operations on longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 56261
diff changeset
3730 static void
fbe6b265bd1a Issue #1087418: Small performance boost for bitwise operations on longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 56261
diff changeset
3731 v_complement(digit *z, digit *a, Py_ssize_t m)
fbe6b265bd1a Issue #1087418: Small performance boost for bitwise operations on longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 56261
diff changeset
3732 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3733 Py_ssize_t i;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3734 digit carry = 1;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3735 for (i = 0; i < m; ++i) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3736 carry += a[i] ^ PyLong_MASK;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3737 z[i] = carry & PyLong_MASK;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3738 carry >>= PyLong_SHIFT;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3739 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3740 assert(carry == 0);
56733
fbe6b265bd1a Issue #1087418: Small performance boost for bitwise operations on longs.
Mark Dickinson <dickinsm@gmail.com>
parents: 56261
diff changeset
3741 }
590
f11fae8ee1e4 Changed to 2's complement bitwise ops. Got rid of ZABS etc.
Guido van Rossum <guido@python.org>
parents: 546
diff changeset
3742
f11fae8ee1e4 Changed to 2's complement bitwise ops. Got rid of ZABS etc.
Guido van Rossum <guido@python.org>
parents: 546
diff changeset
3743 /* Bitwise and/xor/or operations */
f11fae8ee1e4 Changed to 2's complement bitwise ops. Got rid of ZABS etc.
Guido van Rossum <guido@python.org>
parents: 546
diff changeset
3744
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3745 static PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
3746 long_bitwise(PyLongObject *a,
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3747 int op, /* '&', '|', '^' */
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3748 PyLongObject *b)
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3749 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3750 int nega, negb, negz;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3751 Py_ssize_t size_a, size_b, size_z, i;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3752 PyLongObject *z;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3753
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3754 /* Bitwise operations for negative numbers operate as though
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3755 on a two's complement representation. So convert arguments
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3756 from sign-magnitude to two's complement, and convert the
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3757 result back to sign-magnitude at the end. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3758
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3759 /* If a is negative, replace it by its two's complement. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3760 size_a = ABS(Py_SIZE(a));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3761 nega = Py_SIZE(a) < 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3762 if (nega) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3763 z = _PyLong_New(size_a);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3764 if (z == NULL)
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3765 return NULL;
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3766 v_complement(z->ob_digit, a->ob_digit, size_a);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3767 a = z;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3768 }
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3769 else
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3770 /* Keep reference count consistent. */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3771 Py_INCREF(a);
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3772
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3773 /* Same for b. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3774 size_b = ABS(Py_SIZE(b));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3775 negb = Py_SIZE(b) < 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3776 if (negb) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3777 z = _PyLong_New(size_b);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3778 if (z == NULL) {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3779 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3780 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3781 }
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3782 v_complement(z->ob_digit, b->ob_digit, size_b);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3783 b = z;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3784 }
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3785 else
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3786 Py_INCREF(b);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3787
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3788 /* Swap a and b if necessary to ensure size_a >= size_b. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3789 if (size_a < size_b) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3790 z = a; a = b; b = z;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3791 size_z = size_a; size_a = size_b; size_b = size_z;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3792 negz = nega; nega = negb; negb = negz;
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3793 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3794
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3795 /* JRH: The original logic here was to allocate the result value (z)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3796 as the longer of the two operands. However, there are some cases
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3797 where the result is guaranteed to be shorter than that: AND of two
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3798 positives, OR of two negatives: use the shorter number. AND with
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3799 mixed signs: use the positive number. OR with mixed signs: use the
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3800 negative number.
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3801 */
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3802 switch (op) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3803 case '^':
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3804 negz = nega ^ negb;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3805 size_z = size_a;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3806 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3807 case '&':
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3808 negz = nega & negb;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3809 size_z = negb ? size_a : size_b;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3810 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3811 case '|':
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3812 negz = nega | negb;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3813 size_z = negb ? size_b : size_a;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3814 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3815 default:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3816 PyErr_BadArgument();
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3817 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3818 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3819
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3820 /* We allow an extra digit if z is negative, to make sure that
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3821 the final two's complement of z doesn't overflow. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3822 z = _PyLong_New(size_z + negz);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3823 if (z == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3824 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3825 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3826 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3827 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3828
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3829 /* Compute digits for overlap of a and b. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3830 switch(op) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3831 case '&':
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3832 for (i = 0; i < size_b; ++i)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3833 z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3834 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3835 case '|':
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3836 for (i = 0; i < size_b; ++i)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3837 z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3838 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3839 case '^':
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3840 for (i = 0; i < size_b; ++i)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3841 z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3842 break;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3843 default:
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3844 PyErr_BadArgument();
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3845 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3846 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3847
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3848 /* Copy any remaining digits of a, inverting if necessary. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3849 if (op == '^' && negb)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3850 for (; i < size_z; ++i)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3851 z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3852 else if (i < size_z)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3853 memcpy(&z->ob_digit[i], &a->ob_digit[i],
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3854 (size_z-i)*sizeof(digit));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3855
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3856 /* Complement result if negative. */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3857 if (negz) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3858 Py_SIZE(z) = -(Py_SIZE(z));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3859 z->ob_digit[size_z] = PyLong_MASK;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3860 v_complement(z->ob_digit, z->ob_digit, size_z+1);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3861 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3862
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3863 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3864 Py_DECREF(b);
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3865 return (PyObject *)long_normalize(z);
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3866 }
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3867
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3868 static PyObject *
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
3869 long_and(PyObject *v, PyObject *w)
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3870 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3871 PyLongObject *a, *b;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3872 PyObject *c;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3873 CONVERT_BINOP(v, w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3874 c = long_bitwise(a, '&', b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3875 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3876 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3877 return c;
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3878 }
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3879
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3880 static PyObject *
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
3881 long_xor(PyObject *v, PyObject *w)
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3882 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3883 PyLongObject *a, *b;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3884 PyObject *c;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3885 CONVERT_BINOP(v, w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3886 c = long_bitwise(a, '^', b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3887 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3888 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3889 return c;
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3890 }
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3891
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3892 static PyObject *
15725
8e402aeca0a3 Make long a new style number type. Sequence repeat is now done here
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 15318
diff changeset
3893 long_or(PyObject *v, PyObject *w)
443
9f85beb1f7c8 Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents: 406
diff changeset
3894 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3895 PyLongObject *a, *b;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3896 PyObject *c;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3897 CONVERT_BINOP(v, w, &a, &b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3898 c = long_bitwise(a, '|', b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3899 Py_DECREF(a);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3900 Py_DECREF(b);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3901 return c;
242
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
3902 }
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
3903
1313
6ee380349c84 * Added gmtime/localtime/mktime and SYSV timezone globals to timemodule.c.
Guido van Rossum <guido@python.org>
parents: 1257
diff changeset
3904 static int
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
3905 long_coerce(PyObject **pv, PyObject **pw)
955
03de67080c95 * classobject.[ch], {float,long,int}object.c, bltinmodule.c:
Guido van Rossum <guido@python.org>
parents: 795
diff changeset
3906 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3907 if (PyInt_Check(*pw)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3908 *pw = PyLong_FromLong(PyInt_AS_LONG(*pw));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3909 if (*pw == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3910 return -1;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3911 Py_INCREF(*pv);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3912 return 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3913 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3914 else if (PyLong_Check(*pw)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3915 Py_INCREF(*pv);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3916 Py_INCREF(*pw);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3917 return 0;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3918 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3919 return 1; /* Can't do it */
955
03de67080c95 * classobject.[ch], {float,long,int}object.c, bltinmodule.c:
Guido van Rossum <guido@python.org>
parents: 795
diff changeset
3920 }
03de67080c95 * classobject.[ch], {float,long,int}object.c, bltinmodule.c:
Guido van Rossum <guido@python.org>
parents: 795
diff changeset
3921
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3922 static PyObject *
26291
d31ddc66b1b5 Change int() so that passing a string, unicode, float or long argument
Walter Dörwald <walter@livinglogic.de>
parents: 26081
diff changeset
3923 long_long(PyObject *v)
d31ddc66b1b5 Change int() so that passing a string, unicode, float or long argument
Walter Dörwald <walter@livinglogic.de>
parents: 26081
diff changeset
3924 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3925 if (PyLong_CheckExact(v))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3926 Py_INCREF(v);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3927 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3928 v = _PyLong_Copy((PyLongObject *)v);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3929 return v;
26291
d31ddc66b1b5 Change int() so that passing a string, unicode, float or long argument
Walter Dörwald <walter@livinglogic.de>
parents: 26081
diff changeset
3930 }
d31ddc66b1b5 Change int() so that passing a string, unicode, float or long argument
Walter Dörwald <walter@livinglogic.de>
parents: 26081
diff changeset
3931
d31ddc66b1b5 Change int() so that passing a string, unicode, float or long argument
Walter Dörwald <walter@livinglogic.de>
parents: 26081
diff changeset
3932 static PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
3933 long_int(PyObject *v)
1049
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3934 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3935 long x;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3936 x = PyLong_AsLong(v);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3937 if (PyErr_Occurred()) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3938 if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3939 PyErr_Clear();
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3940 if (PyLong_CheckExact(v)) {
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3941 Py_INCREF(v);
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3942 return v;
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3943 }
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3944 else
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
3945 return _PyLong_Copy((PyLongObject *)v);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3946 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3947 else
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3948 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3949 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3950 return PyInt_FromLong(x);
1049
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3951 }
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3952
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3953 static PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
3954 long_float(PyObject *v)
1049
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3955 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3956 double result;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3957 result = PyLong_AsDouble(v);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3958 if (result == -1.0 && PyErr_Occurred())
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3959 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3960 return PyFloat_FromDouble(result);
1049
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3961 }
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3962
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3963 static PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
3964 long_oct(PyObject *v)
1049
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3965 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3966 return _PyLong_Format(v, 8, 1, 0);
1049
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3967 }
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3968
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3969 static PyObject *
13406
a503af7e7fb7 Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
3970 long_hex(PyObject *v)
1049
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3971 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3972 return _PyLong_Format(v, 16, 1, 0);
1049
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3973 }
24280
1598a1e473e2 staticforward bites the dust.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 24231
diff changeset
3974
1598a1e473e2 staticforward bites the dust.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 24231
diff changeset
3975 static PyObject *
19552
6c30d20d27f2 Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents: 19343
diff changeset
3976 long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
1049
2ed511171809 Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents: 958
diff changeset
3977
18933
09df3254b49d Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents: 18607
diff changeset
3978 static PyObject *
09df3254b49d Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents: 18607
diff changeset
3979 long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
09df3254b49d Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents: 18607
diff changeset
3980 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3981 PyObject *x = NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3982 int base = -909; /* unlikely! */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3983 static char *kwlist[] = {"x", "base", 0};
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3984
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3985 if (type != &PyLong_Type)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3986 return long_subtype_new(type, args, kwds); /* Wimp out */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3987 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3988 &x, &base))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3989 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3990 if (x == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3991 return PyLong_FromLong(0L);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3992 if (base == -909)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3993 return PyNumber_Long(x);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3994 else if (PyString_Check(x)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3995 /* Since PyLong_FromString doesn't have a length parameter,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3996 * check here for possible NULs in the string. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3997 char *string = PyString_AS_STRING(x);
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
3998 if (strlen(string) != (size_t)PyString_Size(x)) {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
3999 /* create a repr() of the input string,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4000 * just like PyLong_FromString does. */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4001 PyObject *srepr;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4002 srepr = PyObject_Repr(x);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4003 if (srepr == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4004 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4005 PyErr_Format(PyExc_ValueError,
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4006 "invalid literal for long() with base %d: %s",
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4007 base, PyString_AS_STRING(srepr));
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4008 Py_DECREF(srepr);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4009 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4010 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4011 return PyLong_FromString(PyString_AS_STRING(x), NULL, base);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4012 }
19343
7257e87e0720 Patch #445762: Support --disable-unicode
Martin v. Löwis <martin@v.loewis.de>
parents: 19051
diff changeset
4013 #ifdef Py_USING_UNICODE
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4014 else if (PyUnicode_Check(x))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4015 return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x),
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4016 PyUnicode_GET_SIZE(x),
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4017 base);
19343
7257e87e0720 Patch #445762: Support --disable-unicode
Martin v. Löwis <martin@v.loewis.de>
parents: 19051
diff changeset
4018 #endif
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4019 else {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4020 PyErr_SetString(PyExc_TypeError,
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4021 "long() can't convert non-string with explicit base");
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4022 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4023 }
18933
09df3254b49d Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents: 18607
diff changeset
4024 }
09df3254b49d Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents: 18607
diff changeset
4025
19552
6c30d20d27f2 Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents: 19343
diff changeset
4026 /* Wimpy, slow approach to tp_new calls for subtypes of long:
6c30d20d27f2 Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents: 19343
diff changeset
4027 first create a regular long from whatever arguments we got,
6c30d20d27f2 Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents: 19343
diff changeset
4028 then allocate a subtype instance and initialize it from
6c30d20d27f2 Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents: 19343
diff changeset
4029 the regular long. The regular long is then thrown away.
6c30d20d27f2 Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents: 19343
diff changeset
4030 */
6c30d20d27f2 Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents: 19343
diff changeset
4031 static PyObject *
6c30d20d27f2 Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents: 19343
diff changeset
4032 long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
6c30d20d27f2 Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents: 19343
diff changeset
4033 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4034 PyLongObject *tmp, *newobj;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4035 Py_ssize_t i, n;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4036
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4037 assert(PyType_IsSubtype(type, &PyLong_Type));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4038 tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4039 if (tmp == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4040 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4041 assert(PyLong_CheckExact(tmp));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4042 n = Py_SIZE(tmp);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4043 if (n < 0)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4044 n = -n;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4045 newobj = (PyLongObject *)type->tp_alloc(type, n);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4046 if (newobj == NULL) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4047 Py_DECREF(tmp);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4048 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4049 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4050 assert(PyLong_Check(newobj));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4051 Py_SIZE(newobj) = Py_SIZE(tmp);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4052 for (i = 0; i < n; i++)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4053 newobj->ob_digit[i] = tmp->ob_digit[i];
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4054 Py_DECREF(tmp);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4055 return (PyObject *)newobj;
19552
6c30d20d27f2 Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents: 19343
diff changeset
4056 }
6c30d20d27f2 Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents: 19343
diff changeset
4057
27521
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4058 static PyObject *
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4059 long_getnewargs(PyLongObject *v)
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4060 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4061 return Py_BuildValue("(N)", _PyLong_Copy(v));
27521
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4062 }
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4063
44432
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
4064 static PyObject *
53675
5aaf24ec43dc Remove unnecessary use of context for long getters.
Mark Dickinson <dickinsm@gmail.com>
parents: 53289
diff changeset
4065 long_get0(PyLongObject *v, void *context) {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4066 return PyLong_FromLong(0L);
53675
5aaf24ec43dc Remove unnecessary use of context for long getters.
Mark Dickinson <dickinsm@gmail.com>
parents: 53289
diff changeset
4067 }
5aaf24ec43dc Remove unnecessary use of context for long getters.
Mark Dickinson <dickinsm@gmail.com>
parents: 53289
diff changeset
4068
5aaf24ec43dc Remove unnecessary use of context for long getters.
Mark Dickinson <dickinsm@gmail.com>
parents: 53289
diff changeset
4069 static PyObject *
5aaf24ec43dc Remove unnecessary use of context for long getters.
Mark Dickinson <dickinsm@gmail.com>
parents: 53289
diff changeset
4070 long_get1(PyLongObject *v, void *context) {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4071 return PyLong_FromLong(1L);
27521
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4072 }
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4073
45381
b7231bf6bfb7 Backport of PEP 3101, Advanced String Formatting, from py3k.
Eric Smith <eric@trueblade.com>
parents: 45262
diff changeset
4074 static PyObject *
b7231bf6bfb7 Backport of PEP 3101, Advanced String Formatting, from py3k.
Eric Smith <eric@trueblade.com>
parents: 45262
diff changeset
4075 long__format__(PyObject *self, PyObject *args)
b7231bf6bfb7 Backport of PEP 3101, Advanced String Formatting, from py3k.
Eric Smith <eric@trueblade.com>
parents: 45262
diff changeset
4076 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4077 PyObject *format_spec;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4078
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4079 if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4080 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4081 if (PyBytes_Check(format_spec))
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4082 return _PyLong_FormatAdvanced(self,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4083 PyBytes_AS_STRING(format_spec),
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4084 PyBytes_GET_SIZE(format_spec));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4085 if (PyUnicode_Check(format_spec)) {
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4086 /* Convert format_spec to a str */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4087 PyObject *result;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4088 PyObject *str_spec = PyObject_Str(format_spec);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4089
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4090 if (str_spec == NULL)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4091 return NULL;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4092
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4093 result = _PyLong_FormatAdvanced(self,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4094 PyBytes_AS_STRING(str_spec),
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4095 PyBytes_GET_SIZE(str_spec));
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4096
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4097 Py_DECREF(str_spec);
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4098 return result;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4099 }
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4100 PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4101 return NULL;
45381
b7231bf6bfb7 Backport of PEP 3101, Advanced String Formatting, from py3k.
Eric Smith <eric@trueblade.com>
parents: 45262
diff changeset
4102 }
b7231bf6bfb7 Backport of PEP 3101, Advanced String Formatting, from py3k.
Eric Smith <eric@trueblade.com>
parents: 45262
diff changeset
4103
47419
88bd07c0a847 Issue #2898: Added sys.getsizeof() to retrieve size of objects in bytes.
Robert Schuppenies <okkotonushi@googlemail.com>
parents: 47392
diff changeset
4104 static PyObject *
88bd07c0a847 Issue #2898: Added sys.getsizeof() to retrieve size of objects in bytes.
Robert Schuppenies <okkotonushi@googlemail.com>
parents: 47392
diff changeset
4105 long_sizeof(PyLongObject *v)
88bd07c0a847 Issue #2898: Added sys.getsizeof() to retrieve size of objects in bytes.
Robert Schuppenies <okkotonushi@googlemail.com>
parents: 47392
diff changeset
4106 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4107 Py_ssize_t res;
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4108
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4109 res = v->ob_type->tp_basicsize + ABS(Py_SIZE(v))*sizeof(digit);
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4110 return PyInt_FromSsize_t(res);
47419
88bd07c0a847 Issue #2898: Added sys.getsizeof() to retrieve size of objects in bytes.
Robert Schuppenies <okkotonushi@googlemail.com>
parents: 47392
diff changeset
4111 }
88bd07c0a847 Issue #2898: Added sys.getsizeof() to retrieve size of objects in bytes.
Robert Schuppenies <okkotonushi@googlemail.com>
parents: 47392
diff changeset
4112
50205
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4113 static PyObject *
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4114 long_bit_length(PyLongObject *v)
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4115 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4116 PyLongObject *result, *x, *y;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4117 Py_ssize_t ndigits, msd_bits = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4118 digit msd;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4119
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4120 assert(v != NULL);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4121 assert(PyLong_Check(v));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4122
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4123 ndigits = ABS(Py_SIZE(v));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4124 if (ndigits == 0)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4125 return PyInt_FromLong(0);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4126
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4127 msd = v->ob_digit[ndigits-1];
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4128 while (msd >= 32) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4129 msd_bits += 6;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4130 msd >>= 6;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4131 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4132 msd_bits += (long)(BitLengthTable[msd]);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4133
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4134 if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4135 return PyInt_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4136
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4137 /* expression above may overflow; use Python integers instead */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4138 result = (PyLongObject *)PyLong_FromSsize_t(ndigits - 1);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4139 if (result == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4140 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4141 x = (PyLongObject *)PyLong_FromLong(PyLong_SHIFT);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4142 if (x == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4143 goto error;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4144 y = (PyLongObject *)long_mul(result, x);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4145 Py_DECREF(x);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4146 if (y == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4147 goto error;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4148 Py_DECREF(result);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4149 result = y;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4150
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4151 x = (PyLongObject *)PyLong_FromLong((long)msd_bits);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4152 if (x == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4153 goto error;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4154 y = (PyLongObject *)long_add(result, x);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4155 Py_DECREF(x);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4156 if (y == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4157 goto error;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4158 Py_DECREF(result);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4159 result = y;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4160
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4161 return (PyObject *)result;
50205
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4162
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4163 error:
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4164 Py_DECREF(result);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4165 return NULL;
50205
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4166 }
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4167
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4168 PyDoc_STRVAR(long_bit_length_doc,
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4169 "long.bit_length() -> int or long\n\
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4170 \n\
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4171 Number of bits necessary to represent self in binary.\n\
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4172 >>> bin(37L)\n\
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4173 '0b100101'\n\
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4174 >>> (37L).bit_length()\n\
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4175 6");
f0db06f49a4e Issue #3439: add bit_length method to int and long.
Mark Dickinson <dickinsm@gmail.com>
parents: 48177
diff changeset
4176
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 46459
diff changeset
4177 #if 0
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 46459
diff changeset
4178 static PyObject *
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 46459
diff changeset
4179 long_is_finite(PyObject *v)
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 46459
diff changeset
4180 {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4181 Py_RETURN_TRUE;
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 46459
diff changeset
4182 }
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 46459
diff changeset
4183 #endif
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 46459
diff changeset
4184
27521
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4185 static PyMethodDef long_methods[] = {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4186 {"conjugate", (PyCFunction)long_long, METH_NOARGS,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4187 "Returns self, the complex conjugate of any long."},
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4188 {"bit_length", (PyCFunction)long_bit_length, METH_NOARGS,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4189 long_bit_length_doc},
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 46459
diff changeset
4190 #if 0
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4191 {"is_finite", (PyCFunction)long_is_finite, METH_NOARGS,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4192 "Returns always True."},
46473
5bc7b20dc04a I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
Christian Heimes <christian@cheimes.de>
parents: 46459
diff changeset
4193 #endif
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4194 {"__trunc__", (PyCFunction)long_long, METH_NOARGS,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4195 "Truncating an Integral returns itself."},
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4196 {"__getnewargs__", (PyCFunction)long_getnewargs, METH_NOARGS},
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4197 {"__format__", (PyCFunction)long__format__, METH_VARARGS},
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4198 {"__sizeof__", (PyCFunction)long_sizeof, METH_NOARGS,
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4199 "Returns size in memory, in bytes"},
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4200 {NULL, NULL} /* sentinel */
27521
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4201 };
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4202
44432
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
4203 static PyGetSetDef long_getset[] = {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4204 {"real",
44432
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
4205 (getter)long_long, (setter)NULL,
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
4206 "the real part of a complex number",
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
4207 NULL},
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4208 {"imag",
53675
5aaf24ec43dc Remove unnecessary use of context for long getters.
Mark Dickinson <dickinsm@gmail.com>
parents: 53289
diff changeset
4209 (getter)long_get0, (setter)NULL,
44432
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
4210 "the imaginary part of a complex number",
53675
5aaf24ec43dc Remove unnecessary use of context for long getters.
Mark Dickinson <dickinsm@gmail.com>
parents: 53289
diff changeset
4211 NULL},
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4212 {"numerator",
44432
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
4213 (getter)long_long, (setter)NULL,
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
4214 "the numerator of a rational number in lowest terms",
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
4215 NULL},
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4216 {"denominator",
53675
5aaf24ec43dc Remove unnecessary use of context for long getters.
Mark Dickinson <dickinsm@gmail.com>
parents: 53289
diff changeset
4217 (getter)long_get1, (setter)NULL,
44432
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
4218 "the denominator of a rational number in lowest terms",
53675
5aaf24ec43dc Remove unnecessary use of context for long getters.
Mark Dickinson <dickinsm@gmail.com>
parents: 53289
diff changeset
4219 NULL},
44432
4f9723d9ca32 Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44350
diff changeset
4220 {NULL} /* Sentinel */
27521
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4221 };
17bfd5dbc0f1 Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents: 27487
diff changeset
4222
23832
ed1ba37a46b7 Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents: 23248
diff changeset
4223 PyDoc_STRVAR(long_doc,
79590
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4224 "long(x=0) -> long\n\
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4225 long(x, base=10) -> long\n\
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4226 \n\
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4227 Convert a number or string to a long integer, or return 0L if no arguments\n\
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4228 are given. If x is floating point, the conversion truncates towards zero.\n\
18933
09df3254b49d Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents: 18607
diff changeset
4229 \n\
79590
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4230 If x is not a number or if base is given, then x must be a string or\n\
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4231 Unicode object representing an integer literal in the given base. The\n\
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4232 literal can be preceded by '+' or '-' and be surrounded by whitespace.\n\
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4233 The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to\n\
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4234 interpret the base from the string as an integer literal.\n\
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4235 >>> int('0b100', base=0)\n\
3b484f53f91b Issue #14783: Backport changes from 3.2.
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 68588
diff changeset
4236 4L");
18933
09df3254b49d Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents: 18607
diff changeset
4237
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
4238 static PyNumberMethods long_as_number = {
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4239 (binaryfunc)long_add, /*nb_add*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4240 (binaryfunc)long_sub, /*nb_subtract*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4241 (binaryfunc)long_mul, /*nb_multiply*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4242 long_classic_div, /*nb_divide*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4243 long_mod, /*nb_remainder*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4244 long_divmod, /*nb_divmod*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4245 long_pow, /*nb_power*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4246 (unaryfunc)long_neg, /*nb_negative*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4247 (unaryfunc)long_long, /*tp_positive*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4248 (unaryfunc)long_abs, /*tp_absolute*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4249 (inquiry)long_nonzero, /*tp_nonzero*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4250 (unaryfunc)long_invert, /*nb_invert*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4251 long_lshift, /*nb_lshift*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4252 (binaryfunc)long_rshift, /*nb_rshift*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4253 long_and, /*nb_and*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4254 long_xor, /*nb_xor*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4255 long_or, /*nb_or*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4256 long_coerce, /*nb_coerce*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4257 long_int, /*nb_int*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4258 long_long, /*nb_long*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4259 long_float, /*nb_float*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4260 long_oct, /*nb_oct*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4261 long_hex, /*nb_hex*/
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4262 0, /* nb_inplace_add */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4263 0, /* nb_inplace_subtract */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4264 0, /* nb_inplace_multiply */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4265 0, /* nb_inplace_divide */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4266 0, /* nb_inplace_remainder */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4267 0, /* nb_inplace_power */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4268 0, /* nb_inplace_lshift */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4269 0, /* nb_inplace_rshift */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4270 0, /* nb_inplace_and */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4271 0, /* nb_inplace_xor */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4272 0, /* nb_inplace_or */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4273 long_div, /* nb_floor_divide */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4274 long_true_divide, /* nb_true_divide */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4275 0, /* nb_inplace_floor_divide */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4276 0, /* nb_inplace_true_divide */
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4277 long_long, /* nb_index */
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4278 };
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4279
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
4280 PyTypeObject PyLong_Type = {
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4281 PyObject_HEAD_INIT(&PyType_Type)
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4282 0, /* ob_size */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4283 "long", /* tp_name */
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4284 offsetof(PyLongObject, ob_digit), /* tp_basicsize */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4285 sizeof(digit), /* tp_itemsize */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4286 long_dealloc, /* tp_dealloc */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4287 0, /* tp_print */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4288 0, /* tp_getattr */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4289 0, /* tp_setattr */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4290 (cmpfunc)long_compare, /* tp_compare */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4291 long_repr, /* tp_repr */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4292 &long_as_number, /* tp_as_number */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4293 0, /* tp_as_sequence */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4294 0, /* tp_as_mapping */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4295 (hashfunc)long_hash, /* tp_hash */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4296 0, /* tp_call */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4297 long_str, /* tp_str */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4298 PyObject_GenericGetAttr, /* tp_getattro */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4299 0, /* tp_setattro */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4300 0, /* tp_as_buffer */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4301 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4302 Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */
61465
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4303 long_doc, /* tp_doc */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4304 0, /* tp_traverse */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4305 0, /* tp_clear */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4306 0, /* tp_richcompare */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4307 0, /* tp_weaklistoffset */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4308 0, /* tp_iter */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4309 0, /* tp_iternext */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4310 long_methods, /* tp_methods */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4311 0, /* tp_members */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4312 long_getset, /* tp_getset */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4313 0, /* tp_base */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4314 0, /* tp_dict */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4315 0, /* tp_descr_get */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4316 0, /* tp_descr_set */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4317 0, /* tp_dictoffset */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4318 0, /* tp_init */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4319 0, /* tp_alloc */
e38335d4df91 Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 55936
diff changeset
4320 long_new, /* tp_new */
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4321 PyObject_Del, /* tp_free */
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4322 };
52233
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4323
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4324 static PyTypeObject Long_InfoType;
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4325
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4326 PyDoc_STRVAR(long_info__doc__,
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4327 "sys.long_info\n\
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4328 \n\
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4329 A struct sequence that holds information about Python's\n\
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4330 internal representation of integers. The attributes are read only.");
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4331
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4332 static PyStructSequence_Field long_info_fields[] = {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4333 {"bits_per_digit", "size of a digit in bits"},
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4334 {"sizeof_digit", "size in bytes of the C type used to represent a digit"},
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4335 {NULL, NULL}
52233
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4336 };
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4337
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4338 static PyStructSequence_Desc long_info_desc = {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4339 "sys.long_info", /* name */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4340 long_info__doc__, /* doc */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4341 long_info_fields, /* fields */
61469
bc0cea584478 Post-detabification cleanup: whitespace fixes and long line rewraps only.
Mark Dickinson <dickinsm@gmail.com>
parents: 61463
diff changeset
4342 2 /* number of fields */
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4343 };
52233
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4344
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4345 PyObject *
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4346 PyLong_GetInfo(void)
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4347 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4348 PyObject* long_info;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4349 int field = 0;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4350 long_info = PyStructSequence_New(&Long_InfoType);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4351 if (long_info == NULL)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4352 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4353 PyStructSequence_SET_ITEM(long_info, field++,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4354 PyInt_FromLong(PyLong_SHIFT));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4355 PyStructSequence_SET_ITEM(long_info, field++,
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4356 PyInt_FromLong(sizeof(digit)));
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4357 if (PyErr_Occurred()) {
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4358 Py_CLEAR(long_info);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4359 return NULL;
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4360 }
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4361 return long_info;
52233
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4362 }
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4363
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4364 int
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4365 _PyLong_Init(void)
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4366 {
61463
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4367 /* initialize long_info */
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4368 if (Long_InfoType.tp_name == 0)
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4369 PyStructSequence_InitType(&Long_InfoType, &long_info_desc);
fd25030223b0 Untabify C files. Will watch buildbots.
Antoine Pitrou <solipsis@pitrou.net>
parents: 61396
diff changeset
4370 return 1;
52233
9b358eae532a Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms.
Mark Dickinson <dickinsm@gmail.com>
parents: 51854
diff changeset
4371 }