Mercurial > cpython-lru_cache-weakref
annotate Objects/longobject.c @ 87690:66c1c9f32567 default tip
Add use_weakref option to functools.lru_cache
The use_weakref option makes lru_cache create weak references to the function
arguments when creating the cache key, which prevents them from staying in the
memory forever even after all other references to them are gone.
This is a proof of concept for http://bugs.python.org/issue19859
| author | Radomir Dopieralski <devel@sheep.art.pl> |
|---|---|
| date | Tue, 03 Dec 2013 16:02:48 +0100 |
| parents | 3055e61f1e66 |
| children |
| rev | line source |
|---|---|
| 230 | 1 /* Long (arbitrary precision) integer object implementation */ |
| 2 | |
| 242 | 3 /* XXX The functional organization of this file is terrible */ |
| 4 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
5 #include "Python.h" |
| 230 | 6 #include "longintrepr.h" |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
7 |
|
53290
41293fa6f0dd
Merged revisions 71772 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52741
diff
changeset
|
8 #include <float.h> |
|
1837
87364d9e3444
New patches by Andrew to fix various problems
Guido van Rossum <guido@python.org>
parents:
1391
diff
changeset
|
9 #include <ctype.h> |
|
51642
b8c4664a6539
Merged revisions 69634 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
51518
diff
changeset
|
10 #include <stddef.h> |
| 230 | 11 |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
12 #ifndef NSMALLPOSINTS |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
13 #define NSMALLPOSINTS 257 |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
14 #endif |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
15 #ifndef NSMALLNEGINTS |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
16 #define NSMALLNEGINTS 5 |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
17 #endif |
|
48567
1ce7e5c5a761
Optimization to stop creating new small longs and use the
Facundo Batista <facundobatista@gmail.com>
parents:
48467
diff
changeset
|
18 |
|
51643
79c2311f33cc
A few more type fixes for py3k that were missed in r69635
Mark Dickinson <dickinsm@gmail.com>
parents:
51642
diff
changeset
|
19 /* convert a PyLong of size 1, 0 or -1 to an sdigit */ |
|
84699
3e7683c49620
longobject.c: add an assertion to ensure that MEDIUM_VALUE() is only called on
Victor Stinner <victor.stinner@gmail.com>
parents:
84698
diff
changeset
|
20 #define MEDIUM_VALUE(x) (assert(-1 <= Py_SIZE(x) && Py_SIZE(x) <= 1), \ |
|
3e7683c49620
longobject.c: add an assertion to ensure that MEDIUM_VALUE() is only called on
Victor Stinner <victor.stinner@gmail.com>
parents:
84698
diff
changeset
|
21 Py_SIZE(x) < 0 ? -(sdigit)(x)->ob_digit[0] : \ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
22 (Py_SIZE(x) == 0 ? (sdigit)0 : \ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
23 (sdigit)(x)->ob_digit[0])) |
|
48567
1ce7e5c5a761
Optimization to stop creating new small longs and use the
Facundo Batista <facundobatista@gmail.com>
parents:
48467
diff
changeset
|
24 #define ABS(x) ((x) < 0 ? -(x) : (x)) |
|
1ce7e5c5a761
Optimization to stop creating new small longs and use the
Facundo Batista <facundobatista@gmail.com>
parents:
48467
diff
changeset
|
25 |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
26 #if NSMALLNEGINTS + NSMALLPOSINTS > 0 |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
27 /* Small integers are preallocated in this array so that they |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
28 can be shared. |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
29 The integers that are preallocated are those in the range |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
30 -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive). |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
31 */ |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
32 static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS]; |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
33 #ifdef COUNT_ALLOCS |
|
79069
5ed83105731d
Issue 15959: Fix type mismatch for quick{_neg}_int_allocs. Thanks Serhiy Storchaka.
Mark Dickinson <mdickinson@enthought.com>
parents:
79004
diff
changeset
|
34 Py_ssize_t quick_int_allocs, quick_neg_int_allocs; |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
35 #endif |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
36 |
|
42110
e4f649c4f457
Merged revisions 55962-56019 via svnmerge from
Guido van Rossum <guido@python.org>
parents:
42084
diff
changeset
|
37 static PyObject * |
|
51643
79c2311f33cc
A few more type fixes for py3k that were missed in r69635
Mark Dickinson <dickinsm@gmail.com>
parents:
51642
diff
changeset
|
38 get_small_int(sdigit ival) |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
39 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
40 PyObject *v = (PyObject*)(small_ints + ival + NSMALLNEGINTS); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
41 Py_INCREF(v); |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
42 #ifdef COUNT_ALLOCS |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
43 if (ival >= 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
44 quick_int_allocs++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
45 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
46 quick_neg_int_allocs++; |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
47 #endif |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
48 return v; |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
49 } |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
50 #define CHECK_SMALL_INT(ival) \ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
51 do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { \ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
52 return get_small_int((sdigit)ival); \ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
53 } while(0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
54 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
55 static PyLongObject * |
|
48567
1ce7e5c5a761
Optimization to stop creating new small longs and use the
Facundo Batista <facundobatista@gmail.com>
parents:
48467
diff
changeset
|
56 maybe_small_long(PyLongObject *v) |
|
1ce7e5c5a761
Optimization to stop creating new small longs and use the
Facundo Batista <facundobatista@gmail.com>
parents:
48467
diff
changeset
|
57 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
58 if (v && ABS(Py_SIZE(v)) <= 1) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
59 sdigit ival = MEDIUM_VALUE(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
60 if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
61 Py_DECREF(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
62 return (PyLongObject *)get_small_int(ival); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
63 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
64 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
65 return v; |
|
48567
1ce7e5c5a761
Optimization to stop creating new small longs and use the
Facundo Batista <facundobatista@gmail.com>
parents:
48467
diff
changeset
|
66 } |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
67 #else |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
68 #define CHECK_SMALL_INT(ival) |
|
48567
1ce7e5c5a761
Optimization to stop creating new small longs and use the
Facundo Batista <facundobatista@gmail.com>
parents:
48467
diff
changeset
|
69 #define maybe_small_long(val) (val) |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
70 #endif |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
71 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
72 /* If a freshly-allocated int is already shared, it must |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
73 be a small integer, so negating it must go to PyLong_FromLong */ |
|
84698
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
74 Py_LOCAL_INLINE(void) |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
75 _PyLong_Negate(PyLongObject **x_p) |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
76 { |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
77 PyLongObject *x; |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
78 |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
79 x = (PyLongObject *)*x_p; |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
80 if (Py_REFCNT(x) == 1) { |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
81 Py_SIZE(x) = -Py_SIZE(x); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
82 return; |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
83 } |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
84 |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
85 *x_p = (PyLongObject *)PyLong_FromLong(-MEDIUM_VALUE(x)); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
86 Py_DECREF(x); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
87 } |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
88 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
89 /* For int multiplication, use the O(N**2) school algorithm unless |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
90 * both operands contain more than KARATSUBA_CUTOFF digits (this |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
91 * being an internal Python int digit, in base BASE). |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
92 */ |
|
33325
1768aff92864
SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents:
29641
diff
changeset
|
93 #define KARATSUBA_CUTOFF 70 |
|
1768aff92864
SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents:
29641
diff
changeset
|
94 #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
|
95 |
|
33327
5452d4ecddd0
SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents:
33325
diff
changeset
|
96 /* 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
|
97 * 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
|
98 * 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
|
99 * 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
|
100 */ |
|
5452d4ecddd0
SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents:
33325
diff
changeset
|
101 #define FIVEARY_CUTOFF 8 |
|
5452d4ecddd0
SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents:
33325
diff
changeset
|
102 |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
103 #define SIGCHECK(PyTryBlock) \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
104 do { \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
105 if (PyErr_CheckSignals()) PyTryBlock \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
106 } while(0) |
|
53290
41293fa6f0dd
Merged revisions 71772 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52741
diff
changeset
|
107 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
108 /* Normalize (remove leading zeros from) an int object. |
| 230 | 109 Doesn't attempt to free the storage--in most cases, due to the nature |
| 110 of the algorithms used, this could save at most be one word anyway. */ | |
| 111 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
112 static PyLongObject * |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
113 long_normalize(PyLongObject *v) |
| 230 | 114 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
115 Py_ssize_t j = ABS(Py_SIZE(v)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
116 Py_ssize_t i = j; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
117 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
118 while (i > 0 && v->ob_digit[i-1] == 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
119 --i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
120 if (i != j) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
121 Py_SIZE(v) = (Py_SIZE(v) < 0) ? -(i) : i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
122 return v; |
| 230 | 123 } |
| 124 | |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
125 /* Allocate a new int object with size digits. |
| 230 | 126 Return NULL and set exception if we run out of memory. */ |
| 127 | |
|
51642
b8c4664a6539
Merged revisions 69634 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
51518
diff
changeset
|
128 #define MAX_LONG_DIGITS \ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
129 ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit)) |
|
51642
b8c4664a6539
Merged revisions 69634 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
51518
diff
changeset
|
130 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
131 PyLongObject * |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
132 _PyLong_New(Py_ssize_t size) |
| 230 | 133 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
134 PyLongObject *result; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
135 /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) + |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
136 sizeof(digit)*size. Previous incarnations of this code used |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
137 sizeof(PyVarObject) instead of the offsetof, but this risks being |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
138 incorrect in the presence of padding between the PyVarObject header |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
139 and the digits. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
140 if (size > (Py_ssize_t)MAX_LONG_DIGITS) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
141 PyErr_SetString(PyExc_OverflowError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
142 "too many digits in integer"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
143 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
144 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
145 result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) + |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
146 size*sizeof(digit)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
147 if (!result) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
148 PyErr_NoMemory(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
149 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
150 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
151 return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size); |
| 230 | 152 } |
| 153 | |
|
19837
5158e4789459
SF bug #460020: bug or feature: unicode() and subclasses.
Tim Peters <tim.peters@gmail.com>
parents:
19787
diff
changeset
|
154 PyObject * |
|
5158e4789459
SF bug #460020: bug or feature: unicode() and subclasses.
Tim Peters <tim.peters@gmail.com>
parents:
19787
diff
changeset
|
155 _PyLong_Copy(PyLongObject *src) |
|
5158e4789459
SF bug #460020: bug or feature: unicode() and subclasses.
Tim Peters <tim.peters@gmail.com>
parents:
19787
diff
changeset
|
156 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
157 PyLongObject *result; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
158 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
159 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
160 assert(src != NULL); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
161 i = Py_SIZE(src); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
162 if (i < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
163 i = -(i); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
164 if (i < 2) { |
|
76440
cdcc6b489862
Issue #14630: Fix an incorrect access of ob_digit[0] for a zero instance of an int subclass.
Mark Dickinson <mdickinson@enthought.com>
parents:
72344
diff
changeset
|
165 sdigit ival = MEDIUM_VALUE(src); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
166 CHECK_SMALL_INT(ival); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
167 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
168 result = _PyLong_New(i); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
169 if (result != NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
170 Py_SIZE(result) = Py_SIZE(src); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
171 while (--i >= 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
172 result->ob_digit[i] = src->ob_digit[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
173 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
174 return (PyObject *)result; |
|
19837
5158e4789459
SF bug #460020: bug or feature: unicode() and subclasses.
Tim Peters <tim.peters@gmail.com>
parents:
19787
diff
changeset
|
175 } |
|
5158e4789459
SF bug #460020: bug or feature: unicode() and subclasses.
Tim Peters <tim.peters@gmail.com>
parents:
19787
diff
changeset
|
176 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
177 /* Create a new int object from a C long int */ |
| 230 | 178 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
179 PyObject * |
|
13406
a503af7e7fb7
Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents:
13256
diff
changeset
|
180 PyLong_FromLong(long ival) |
| 230 | 181 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
182 PyLongObject *v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
183 unsigned long abs_ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
184 unsigned long t; /* unsigned so >> doesn't propagate sign bit */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
185 int ndigits = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
186 int sign = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
187 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
188 CHECK_SMALL_INT(ival); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
189 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
190 if (ival < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
191 /* negate: can't write this as abs_ival = -ival since that |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
192 invokes undefined behaviour when ival is LONG_MIN */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
193 abs_ival = 0U-(unsigned long)ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
194 sign = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
195 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
196 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
197 abs_ival = (unsigned long)ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
198 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
199 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
200 /* Fast path for single-digit ints */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
201 if (!(abs_ival >> PyLong_SHIFT)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
202 v = _PyLong_New(1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
203 if (v) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
204 Py_SIZE(v) = sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
205 v->ob_digit[0] = Py_SAFE_DOWNCAST( |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
206 abs_ival, unsigned long, digit); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
207 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
208 return (PyObject*)v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
209 } |
|
18114
31cd0db0f09f
PyLong_From{Unsigned,}Long: count the # of digits first, so no more space
Tim Peters <tim.peters@gmail.com>
parents:
18110
diff
changeset
|
210 |
|
53541
1a451ff6583c
Typo fix. Thanks Damien Diederen.
Mark Dickinson <dickinsm@gmail.com>
parents:
53290
diff
changeset
|
211 #if PyLong_SHIFT==15 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
212 /* 2 digits */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
213 if (!(abs_ival >> 2*PyLong_SHIFT)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
214 v = _PyLong_New(2); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
215 if (v) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
216 Py_SIZE(v) = 2*sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
217 v->ob_digit[0] = Py_SAFE_DOWNCAST( |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
218 abs_ival & PyLong_MASK, unsigned long, digit); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
219 v->ob_digit[1] = Py_SAFE_DOWNCAST( |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
220 abs_ival >> PyLong_SHIFT, unsigned long, digit); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
221 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
222 return (PyObject*)v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
223 } |
|
52215
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
224 #endif |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
225 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
226 /* Larger numbers: loop to determine number of digits */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
227 t = abs_ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
228 while (t) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
229 ++ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
230 t >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
231 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
232 v = _PyLong_New(ndigits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
233 if (v != NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
234 digit *p = v->ob_digit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
235 Py_SIZE(v) = ndigits*sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
236 t = abs_ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
237 while (t) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
238 *p++ = Py_SAFE_DOWNCAST( |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
239 t & PyLong_MASK, unsigned long, digit); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
240 t >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
241 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
242 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
243 return (PyObject *)v; |
| 230 | 244 } |
| 245 | |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
246 /* Create a new int object from a C unsigned long int */ |
|
4870
68f4134869db
Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents:
4587
diff
changeset
|
247 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
248 PyObject * |
|
13406
a503af7e7fb7
Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents:
13256
diff
changeset
|
249 PyLong_FromUnsignedLong(unsigned long ival) |
|
4870
68f4134869db
Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents:
4587
diff
changeset
|
250 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
251 PyLongObject *v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
252 unsigned long t; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
253 int ndigits = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
254 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
255 if (ival < PyLong_BASE) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
256 return PyLong_FromLong(ival); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
257 /* Count the number of Python digits. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
258 t = (unsigned long)ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
259 while (t) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
260 ++ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
261 t >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
262 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
263 v = _PyLong_New(ndigits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
264 if (v != NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
265 digit *p = v->ob_digit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
266 Py_SIZE(v) = ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
267 while (ival) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
268 *p++ = (digit)(ival & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
269 ival >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
270 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
271 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
272 return (PyObject *)v; |
|
4870
68f4134869db
Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents:
4587
diff
changeset
|
273 } |
|
68f4134869db
Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents:
4587
diff
changeset
|
274 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
275 /* Create a new int object from a C double */ |
|
254
71b0bd5ed162
Added dnewlongobject(), function to convert double to long int.
Guido van Rossum <guido@python.org>
parents:
250
diff
changeset
|
276 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
277 PyObject * |
|
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
278 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
|
279 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
280 PyLongObject *v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
281 double frac; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
282 int i, ndig, expo, neg; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
283 neg = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
284 if (Py_IS_INFINITY(dval)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
285 PyErr_SetString(PyExc_OverflowError, |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
286 "cannot convert float infinity to integer"); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
287 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
288 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
289 if (Py_IS_NAN(dval)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
290 PyErr_SetString(PyExc_ValueError, |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
291 "cannot convert float NaN to integer"); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
292 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
293 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
294 if (dval < 0.0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
295 neg = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
296 dval = -dval; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
297 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
298 frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
299 if (expo <= 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
300 return PyLong_FromLong(0L); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
301 ndig = (expo-1) / PyLong_SHIFT + 1; /* Number of 'digits' in result */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
302 v = _PyLong_New(ndig); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
303 if (v == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
304 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
305 frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
306 for (i = ndig; --i >= 0; ) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
307 digit bits = (digit)frac; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
308 v->ob_digit[i] = bits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
309 frac = frac - (double)bits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
310 frac = ldexp(frac, PyLong_SHIFT); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
311 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
312 if (neg) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
313 Py_SIZE(v) = -(Py_SIZE(v)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
314 return (PyObject *)v; |
|
254
71b0bd5ed162
Added dnewlongobject(), function to convert double to long int.
Guido van Rossum <guido@python.org>
parents:
250
diff
changeset
|
315 } |
|
71b0bd5ed162
Added dnewlongobject(), function to convert double to long int.
Guido van Rossum <guido@python.org>
parents:
250
diff
changeset
|
316 |
|
40450
cc992d75d5b3
Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents:
40401
diff
changeset
|
317 /* Checking for overflow in PyLong_AsLong is a PITA since C doesn't define |
|
cc992d75d5b3
Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents:
40401
diff
changeset
|
318 * anything about what happens when a signed integer operation overflows, |
|
cc992d75d5b3
Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents:
40401
diff
changeset
|
319 * and some compilers think they're doing you a favor by being "clever" |
|
cc992d75d5b3
Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents:
40401
diff
changeset
|
320 * then. The bit pattern for the largest postive signed long is |
|
cc992d75d5b3
Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents:
40401
diff
changeset
|
321 * (unsigned long)LONG_MAX, and for the smallest negative signed long |
|
cc992d75d5b3
Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents:
40401
diff
changeset
|
322 * it is abs(LONG_MIN), which we could write -(unsigned long)LONG_MIN. |
|
cc992d75d5b3
Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents:
40401
diff
changeset
|
323 * However, some other compilers warn about applying unary minus to an |
|
cc992d75d5b3
Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents:
40401
diff
changeset
|
324 * unsigned operand. Hence the weird "0-". |
|
cc992d75d5b3
Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents:
40401
diff
changeset
|
325 */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
326 #define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
327 #define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN) |
|
40450
cc992d75d5b3
Four months of trunk changes (including a few releases...)
Thomas Wouters <thomas@python.org>
parents:
40401
diff
changeset
|
328 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
329 /* Get a C long int from an int object or any object that has an __int__ |
|
73075
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
330 method. |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
331 |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
332 On overflow, return -1 and set *overflow to 1 or -1 depending on the sign of |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
333 the result. Otherwise *overflow is 0. |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
334 |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
335 For other errors (e.g., TypeError), return -1 and set an error condition. |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
336 In this case *overflow will be 0. |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
337 */ |
| 230 | 338 |
| 339 long | |
|
44158
81e0c0e2a8c1
Remove PyInt_CheckExact. Add PyLong_AsLongAndOverflow.
Martin v. Löwis <martin@v.loewis.de>
parents:
44099
diff
changeset
|
340 PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) |
| 230 | 341 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
342 /* This version by Tim Peters */ |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
343 PyLongObject *v; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
344 unsigned long x, prev; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
345 long res; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
346 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
347 int sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
348 int do_decref = 0; /* if nb_int was called */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
349 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
350 *overflow = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
351 if (vv == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
352 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
353 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
354 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
355 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
356 if (!PyLong_Check(vv)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
357 PyNumberMethods *nb; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
358 nb = vv->ob_type->tp_as_number; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
359 if (nb == NULL || nb->nb_int == NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
360 PyErr_SetString(PyExc_TypeError, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
361 "an integer is required"); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
362 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
363 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
364 vv = (*nb->nb_int) (vv); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
365 if (vv == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
366 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
367 do_decref = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
368 if (!PyLong_Check(vv)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
369 Py_DECREF(vv); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
370 PyErr_SetString(PyExc_TypeError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
371 "nb_int should return int object"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
372 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
373 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
374 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
375 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
376 res = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
377 v = (PyLongObject *)vv; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
378 i = Py_SIZE(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
379 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
380 switch (i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
381 case -1: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
382 res = -(sdigit)v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
383 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
384 case 0: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
385 res = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
386 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
387 case 1: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
388 res = v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
389 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
390 default: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
391 sign = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
392 x = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
393 if (i < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
394 sign = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
395 i = -(i); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
396 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
397 while (--i >= 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
398 prev = x; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
399 x = (x << PyLong_SHIFT) | v->ob_digit[i]; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
400 if ((x >> PyLong_SHIFT) != prev) { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
401 *overflow = sign; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
402 goto exit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
403 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
404 } |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
405 /* Haven't lost any bits, but casting to long requires extra |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
406 * care (see comment above). |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
407 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
408 if (x <= (unsigned long)LONG_MAX) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
409 res = (long)x * sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
410 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
411 else if (sign < 0 && x == PY_ABS_LONG_MIN) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
412 res = LONG_MIN; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
413 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
414 else { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
415 *overflow = sign; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
416 /* res is already set to -1 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
417 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
418 } |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
419 exit: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
420 if (do_decref) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
421 Py_DECREF(vv); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
422 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
423 return res; |
| 230 | 424 } |
| 425 | |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
426 /* Get a C long int from an int object or any object that has an __int__ |
|
73075
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
427 method. Return -1 and set an error if overflow occurs. */ |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
428 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
429 long |
|
44158
81e0c0e2a8c1
Remove PyInt_CheckExact. Add PyLong_AsLongAndOverflow.
Martin v. Löwis <martin@v.loewis.de>
parents:
44099
diff
changeset
|
430 PyLong_AsLong(PyObject *obj) |
|
81e0c0e2a8c1
Remove PyInt_CheckExact. Add PyLong_AsLongAndOverflow.
Martin v. Löwis <martin@v.loewis.de>
parents:
44099
diff
changeset
|
431 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
432 int overflow; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
433 long result = PyLong_AsLongAndOverflow(obj, &overflow); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
434 if (overflow) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
435 /* XXX: could be cute and give a different |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
436 message for overflow == -1 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
437 PyErr_SetString(PyExc_OverflowError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
438 "Python int too large to convert to C long"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
439 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
440 return result; |
|
44158
81e0c0e2a8c1
Remove PyInt_CheckExact. Add PyLong_AsLongAndOverflow.
Martin v. Löwis <martin@v.loewis.de>
parents:
44099
diff
changeset
|
441 } |
|
81e0c0e2a8c1
Remove PyInt_CheckExact. Add PyLong_AsLongAndOverflow.
Martin v. Löwis <martin@v.loewis.de>
parents:
44099
diff
changeset
|
442 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
443 /* Get a C int from an int object or any object that has an __int__ |
|
81587
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
444 method. Return -1 and set an error if overflow occurs. */ |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
445 |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
446 int |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
447 _PyLong_AsInt(PyObject *obj) |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
448 { |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
449 int overflow; |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
450 long result = PyLong_AsLongAndOverflow(obj, &overflow); |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
451 if (overflow || result > INT_MAX || result < INT_MIN) { |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
452 /* XXX: could be cute and give a different |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
453 message for overflow == -1 */ |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
454 PyErr_SetString(PyExc_OverflowError, |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
455 "Python int too large to convert to C int"); |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
456 return -1; |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
457 } |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
458 return (int)result; |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
459 } |
|
974ace29ee2d
Issue #15989: Fix several occurrences of integer overflow
Serhiy Storchaka <storchaka@gmail.com>
parents:
81124
diff
changeset
|
460 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
461 /* Get a Py_ssize_t from an int object. |
|
39610
3674f20ac781
Merge current trunk into p3yk. This includes the PyNumber_Index API change,
Thomas Wouters <thomas@python.org>
parents:
39574
diff
changeset
|
462 Returns -1 and sets an error condition if overflow occurs. */ |
|
3674f20ac781
Merge current trunk into p3yk. This includes the PyNumber_Index API change,
Thomas Wouters <thomas@python.org>
parents:
39574
diff
changeset
|
463 |
|
3674f20ac781
Merge current trunk into p3yk. This includes the PyNumber_Index API change,
Thomas Wouters <thomas@python.org>
parents:
39574
diff
changeset
|
464 Py_ssize_t |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
465 PyLong_AsSsize_t(PyObject *vv) { |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
466 PyLongObject *v; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
467 size_t x, prev; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
468 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
469 int sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
470 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
471 if (vv == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
472 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
473 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
474 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
475 if (!PyLong_Check(vv)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
476 PyErr_SetString(PyExc_TypeError, "an integer is required"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
477 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
478 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
479 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
480 v = (PyLongObject *)vv; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
481 i = Py_SIZE(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
482 switch (i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
483 case -1: return -(sdigit)v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
484 case 0: return 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
485 case 1: return v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
486 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
487 sign = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
488 x = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
489 if (i < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
490 sign = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
491 i = -(i); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
492 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
493 while (--i >= 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
494 prev = x; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
495 x = (x << PyLong_SHIFT) | v->ob_digit[i]; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
496 if ((x >> PyLong_SHIFT) != prev) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
497 goto overflow; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
498 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
499 /* Haven't lost any bits, but casting to a signed type requires |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
500 * extra care (see comment above). |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
501 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
502 if (x <= (size_t)PY_SSIZE_T_MAX) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
503 return (Py_ssize_t)x * sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
504 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
505 else if (sign < 0 && x == PY_ABS_SSIZE_T_MIN) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
506 return PY_SSIZE_T_MIN; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
507 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
508 /* else overflow */ |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
509 |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
510 overflow: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
511 PyErr_SetString(PyExc_OverflowError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
512 "Python int too large to convert to C ssize_t"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
513 return -1; |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
514 } |
|
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
515 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
516 /* Get a C unsigned long int from an int object. |
|
4870
68f4134869db
Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents:
4587
diff
changeset
|
517 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
|
518 |
|
68f4134869db
Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents:
4587
diff
changeset
|
519 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
|
520 PyLong_AsUnsignedLong(PyObject *vv) |
|
4870
68f4134869db
Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents:
4587
diff
changeset
|
521 { |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
522 PyLongObject *v; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
523 unsigned long x, prev; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
524 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
525 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
526 if (vv == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
527 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
528 return (unsigned long)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
529 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
530 if (!PyLong_Check(vv)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
531 PyErr_SetString(PyExc_TypeError, "an integer is required"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
532 return (unsigned long)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
533 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
534 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
535 v = (PyLongObject *)vv; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
536 i = Py_SIZE(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
537 x = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
538 if (i < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
539 PyErr_SetString(PyExc_OverflowError, |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
540 "can't convert negative value to unsigned int"); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
541 return (unsigned long) -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
542 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
543 switch (i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
544 case 0: return 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
545 case 1: return v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
546 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
547 while (--i >= 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
548 prev = x; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
549 x = (x << PyLong_SHIFT) | v->ob_digit[i]; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
550 if ((x >> PyLong_SHIFT) != prev) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
551 PyErr_SetString(PyExc_OverflowError, |
|
84983
dab7d6f33b87
Minor consistency fixes for some longobject.c exception messages:
Mark Dickinson <dickinsm@gmail.com>
parents:
84793
diff
changeset
|
552 "Python int too large to convert " |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
553 "to C unsigned long"); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
554 return (unsigned long) -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
555 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
556 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
557 return x; |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
558 } |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
559 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
560 /* Get a C size_t from an int object. Returns (size_t)-1 and sets |
|
72344
d14f717b5e3d
Issue #12963: PyLong_AsSize_t() now returns (size_t)-1 in all error cases.
Stefan Krah <skrah@bytereef.org>
parents:
68586
diff
changeset
|
561 an error condition if overflow occurs. */ |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
562 |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
563 size_t |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
564 PyLong_AsSize_t(PyObject *vv) |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
565 { |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
566 PyLongObject *v; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
567 size_t x, prev; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
568 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
569 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
570 if (vv == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
571 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
572 return (size_t) -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
573 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
574 if (!PyLong_Check(vv)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
575 PyErr_SetString(PyExc_TypeError, "an integer is required"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
576 return (size_t)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
577 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
578 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
579 v = (PyLongObject *)vv; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
580 i = Py_SIZE(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
581 x = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
582 if (i < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
583 PyErr_SetString(PyExc_OverflowError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
584 "can't convert negative value to size_t"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
585 return (size_t) -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
586 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
587 switch (i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
588 case 0: return 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
589 case 1: return v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
590 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
591 while (--i >= 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
592 prev = x; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
593 x = (x << PyLong_SHIFT) | v->ob_digit[i]; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
594 if ((x >> PyLong_SHIFT) != prev) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
595 PyErr_SetString(PyExc_OverflowError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
596 "Python int too large to convert to C size_t"); |
|
72344
d14f717b5e3d
Issue #12963: PyLong_AsSize_t() now returns (size_t)-1 in all error cases.
Stefan Krah <skrah@bytereef.org>
parents:
68586
diff
changeset
|
597 return (size_t) -1; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
598 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
599 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
600 return x; |
|
4870
68f4134869db
Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents:
4587
diff
changeset
|
601 } |
|
68f4134869db
Added PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong().
Guido van Rossum <guido@python.org>
parents:
4587
diff
changeset
|
602 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
603 /* Get a C unsigned long int from an int object, ignoring the high bits. |
|
28652
28a2975514cd
SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents:
28437
diff
changeset
|
604 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
|
605 |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
606 static unsigned long |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
607 _PyLong_AsUnsignedLongMask(PyObject *vv) |
|
28652
28a2975514cd
SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents:
28437
diff
changeset
|
608 { |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
609 PyLongObject *v; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
610 unsigned long x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
611 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
612 int sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
613 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
614 if (vv == NULL || !PyLong_Check(vv)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
615 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
616 return (unsigned long) -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
617 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
618 v = (PyLongObject *)vv; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
619 i = Py_SIZE(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
620 switch (i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
621 case 0: return 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
622 case 1: return v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
623 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
624 sign = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
625 x = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
626 if (i < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
627 sign = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
628 i = -i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
629 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
630 while (--i >= 0) { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
631 x = (x << PyLong_SHIFT) | v->ob_digit[i]; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
632 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
633 return x * sign; |
|
28652
28a2975514cd
SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents:
28437
diff
changeset
|
634 } |
|
28a2975514cd
SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents:
28437
diff
changeset
|
635 |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
636 unsigned long |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
637 PyLong_AsUnsignedLongMask(PyObject *op) |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
638 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
639 PyNumberMethods *nb; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
640 PyLongObject *lo; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
641 unsigned long val; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
642 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
643 if (op && PyLong_Check(op)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
644 return _PyLong_AsUnsignedLongMask(op); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
645 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
646 if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
647 nb->nb_int == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
648 PyErr_SetString(PyExc_TypeError, "an integer is required"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
649 return (unsigned long)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
650 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
651 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
652 lo = (PyLongObject*) (*nb->nb_int) (op); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
653 if (lo == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
654 return (unsigned long)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
655 if (PyLong_Check(lo)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
656 val = _PyLong_AsUnsignedLongMask((PyObject *)lo); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
657 Py_DECREF(lo); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
658 if (PyErr_Occurred()) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
659 return (unsigned long)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
660 return val; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
661 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
662 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
663 { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
664 Py_DECREF(lo); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
665 PyErr_SetString(PyExc_TypeError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
666 "nb_int should return int object"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
667 return (unsigned long)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
668 } |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
669 } |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
670 |
|
27549
7fcdeeb16ec0
_PyLong_NumBits(): The definition of this was too specific to the quirky
Tim Peters <tim.peters@gmail.com>
parents:
27521
diff
changeset
|
671 int |
|
7fcdeeb16ec0
_PyLong_NumBits(): The definition of this was too specific to the quirky
Tim Peters <tim.peters@gmail.com>
parents:
27521
diff
changeset
|
672 _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
|
673 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
674 PyLongObject *v = (PyLongObject *)vv; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
675 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
676 assert(v != NULL); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
677 assert(PyLong_Check(v)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
678 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
679 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
|
680 } |
|
7fcdeeb16ec0
_PyLong_NumBits(): The definition of this was too specific to the quirky
Tim Peters <tim.peters@gmail.com>
parents:
27521
diff
changeset
|
681 |
|
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
|
682 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
|
683 _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
|
684 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
685 PyLongObject *v = (PyLongObject *)vv; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
686 size_t result = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
687 Py_ssize_t ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
688 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
689 assert(v != NULL); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
690 assert(PyLong_Check(v)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
691 ndigits = ABS(Py_SIZE(v)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
692 assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
693 if (ndigits > 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
694 digit msd = v->ob_digit[ndigits - 1]; |
|
79532
906ae6485cb8
Issue #16096: Fix signed overflow in Objects/longobject.c. Thanks Serhiy Storchaka.
Mark Dickinson <mdickinson@enthought.com>
parents:
79070
diff
changeset
|
695 if ((size_t)(ndigits - 1) > PY_SIZE_MAX / (size_t)PyLong_SHIFT) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
696 goto Overflow; |
|
79532
906ae6485cb8
Issue #16096: Fix signed overflow in Objects/longobject.c. Thanks Serhiy Storchaka.
Mark Dickinson <mdickinson@enthought.com>
parents:
79070
diff
changeset
|
697 result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
698 do { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
699 ++result; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
700 if (result == 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
701 goto Overflow; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
702 msd >>= 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
703 } while (msd); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
704 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
705 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
|
706 |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
707 Overflow: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
708 PyErr_SetString(PyExc_OverflowError, "int has too many bits " |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
709 "to express in a platform size_t"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
710 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
|
711 } |
|
0904d878b8f1
Added new private API function _PyLong_NumBits. This will be used at the
Tim Peters <tim.peters@gmail.com>
parents:
26867
diff
changeset
|
712 |
|
18082
dd09f11fa40d
Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents:
15946
diff
changeset
|
713 PyObject * |
|
dd09f11fa40d
Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents:
15946
diff
changeset
|
714 _PyLong_FromByteArray(const unsigned char* bytes, size_t n, |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
715 int little_endian, int is_signed) |
|
18082
dd09f11fa40d
Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents:
15946
diff
changeset
|
716 { |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
717 const unsigned char* pstartbyte; /* LSB of bytes */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
718 int incr; /* direction to move pstartbyte */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
719 const unsigned char* pendbyte; /* MSB of bytes */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
720 size_t numsignificantbytes; /* number of bytes that matter */ |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
721 Py_ssize_t ndigits; /* number of Python int digits */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
722 PyLongObject* v; /* result */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
723 Py_ssize_t idigit = 0; /* next free index in v->ob_digit */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
724 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
725 if (n == 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
726 return PyLong_FromLong(0L); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
727 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
728 if (little_endian) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
729 pstartbyte = bytes; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
730 pendbyte = bytes + n - 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
731 incr = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
732 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
733 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
734 pstartbyte = bytes + n - 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
735 pendbyte = bytes; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
736 incr = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
737 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
738 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
739 if (is_signed) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
740 is_signed = *pendbyte >= 0x80; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
741 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
742 /* Compute numsignificantbytes. This consists of finding the most |
|
68585
bf94b6a73fc8
#11565: Fix several typos. Patch by Piotr Kasprzyk.
Ezio Melotti <ezio.melotti@gmail.com>
parents:
68488
diff
changeset
|
743 significant byte. Leading 0 bytes are insignificant if the number |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
744 is positive, and leading 0xff bytes if negative. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
745 { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
746 size_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
747 const unsigned char* p = pendbyte; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
748 const int pincr = -incr; /* search MSB to LSB */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
749 const unsigned char insignficant = is_signed ? 0xff : 0x00; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
750 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
751 for (i = 0; i < n; ++i, p += pincr) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
752 if (*p != insignficant) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
753 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
754 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
755 numsignificantbytes = n - i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
756 /* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
757 actually has 2 significant bytes. OTOH, 0xff0001 == |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
758 -0x00ffff, so we wouldn't *need* to bump it there; but we |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
759 do for 0xffff = -0x0001. To be safe without bothering to |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
760 check every case, bump it regardless. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
761 if (is_signed && numsignificantbytes < n) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
762 ++numsignificantbytes; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
763 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
764 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
765 /* How many Python int digits do we need? We have |
|
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
766 8*numsignificantbytes bits, and each Python int digit has |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
767 PyLong_SHIFT bits, so it's the ceiling of the quotient. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
768 /* catch overflow before it happens */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
769 if (numsignificantbytes > (PY_SSIZE_T_MAX - PyLong_SHIFT) / 8) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
770 PyErr_SetString(PyExc_OverflowError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
771 "byte array too long to convert to int"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
772 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
773 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
774 ndigits = (numsignificantbytes * 8 + PyLong_SHIFT - 1) / PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
775 v = _PyLong_New(ndigits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
776 if (v == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
777 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
778 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
779 /* Copy the bits over. The tricky parts are computing 2's-comp on |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
780 the fly for signed numbers, and dealing with the mismatch between |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
781 8-bit bytes and (probably) 15-bit Python digits.*/ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
782 { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
783 size_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
784 twodigits carry = 1; /* for 2's-comp calculation */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
785 twodigits accum = 0; /* sliding register */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
786 unsigned int accumbits = 0; /* number of bits in accum */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
787 const unsigned char* p = pstartbyte; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
788 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
789 for (i = 0; i < numsignificantbytes; ++i, p += incr) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
790 twodigits thisbyte = *p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
791 /* Compute correction for 2's comp, if needed. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
792 if (is_signed) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
793 thisbyte = (0xff ^ thisbyte) + carry; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
794 carry = thisbyte >> 8; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
795 thisbyte &= 0xff; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
796 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
797 /* Because we're going LSB to MSB, thisbyte is |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
798 more significant than what's already in accum, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
799 so needs to be prepended to accum. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
800 accum |= (twodigits)thisbyte << accumbits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
801 accumbits += 8; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
802 if (accumbits >= PyLong_SHIFT) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
803 /* There's enough to fill a Python digit. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
804 assert(idigit < ndigits); |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
805 v->ob_digit[idigit] = (digit)(accum & PyLong_MASK); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
806 ++idigit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
807 accum >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
808 accumbits -= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
809 assert(accumbits < PyLong_SHIFT); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
810 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
811 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
812 assert(accumbits < PyLong_SHIFT); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
813 if (accumbits) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
814 assert(idigit < ndigits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
815 v->ob_digit[idigit] = (digit)accum; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
816 ++idigit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
817 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
818 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
819 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
820 Py_SIZE(v) = is_signed ? -idigit : idigit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
821 return (PyObject *)long_normalize(v); |
|
18082
dd09f11fa40d
Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents:
15946
diff
changeset
|
822 } |
|
dd09f11fa40d
Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents:
15946
diff
changeset
|
823 |
|
dd09f11fa40d
Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents:
15946
diff
changeset
|
824 int |
|
dd09f11fa40d
Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents:
15946
diff
changeset
|
825 _PyLong_AsByteArray(PyLongObject* v, |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
826 unsigned char* bytes, size_t n, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
827 int little_endian, int is_signed) |
|
18082
dd09f11fa40d
Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents:
15946
diff
changeset
|
828 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
829 Py_ssize_t i; /* index into v->ob_digit */ |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
830 Py_ssize_t ndigits; /* |v->ob_size| */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
831 twodigits accum; /* sliding register */ |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
832 unsigned int accumbits; /* # bits in accum */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
833 int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
834 digit carry; /* for computing 2's-comp */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
835 size_t j; /* # bytes filled */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
836 unsigned char* p; /* pointer to next byte in bytes */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
837 int pincr; /* direction to move p */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
838 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
839 assert(v != NULL && PyLong_Check(v)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
840 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
841 if (Py_SIZE(v) < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
842 ndigits = -(Py_SIZE(v)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
843 if (!is_signed) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
844 PyErr_SetString(PyExc_OverflowError, |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
845 "can't convert negative int to unsigned"); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
846 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
847 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
848 do_twos_comp = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
849 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
850 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
851 ndigits = Py_SIZE(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
852 do_twos_comp = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
853 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
854 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
855 if (little_endian) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
856 p = bytes; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
857 pincr = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
858 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
859 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
860 p = bytes + n - 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
861 pincr = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
862 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
863 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
864 /* Copy over all the Python digits. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
865 It's crucial that every Python digit except for the MSD contribute |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
866 exactly PyLong_SHIFT bits to the total, so first assert that the int is |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
867 normalized. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
868 assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
869 j = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
870 accum = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
871 accumbits = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
872 carry = do_twos_comp ? 1 : 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
873 for (i = 0; i < ndigits; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
874 digit thisdigit = v->ob_digit[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
875 if (do_twos_comp) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
876 thisdigit = (thisdigit ^ PyLong_MASK) + carry; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
877 carry = thisdigit >> PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
878 thisdigit &= PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
879 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
880 /* Because we're going LSB to MSB, thisdigit is more |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
881 significant than what's already in accum, so needs to be |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
882 prepended to accum. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
883 accum |= (twodigits)thisdigit << accumbits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
884 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
885 /* The most-significant digit may be (probably is) at least |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
886 partly empty. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
887 if (i == ndigits - 1) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
888 /* Count # of sign bits -- they needn't be stored, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
889 * although for signed conversion we need later to |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
890 * make sure at least one sign bit gets stored. */ |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
891 digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : thisdigit; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
892 while (s != 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
893 s >>= 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
894 accumbits++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
895 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
896 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
897 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
898 accumbits += PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
899 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
900 /* Store as many bytes as possible. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
901 while (accumbits >= 8) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
902 if (j >= n) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
903 goto Overflow; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
904 ++j; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
905 *p = (unsigned char)(accum & 0xff); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
906 p += pincr; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
907 accumbits -= 8; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
908 accum >>= 8; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
909 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
910 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
911 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
912 /* Store the straggler (if any). */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
913 assert(accumbits < 8); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
914 assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
915 if (accumbits > 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
916 if (j >= n) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
917 goto Overflow; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
918 ++j; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
919 if (do_twos_comp) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
920 /* Fill leading bits of the byte with sign bits |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
921 (appropriately pretending that the int had an |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
922 infinite supply of sign bits). */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
923 accum |= (~(twodigits)0) << accumbits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
924 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
925 *p = (unsigned char)(accum & 0xff); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
926 p += pincr; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
927 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
928 else if (j == n && n > 0 && is_signed) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
929 /* The main loop filled the byte array exactly, so the code |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
930 just above didn't get to ensure there's a sign bit, and the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
931 loop below wouldn't add one either. Make sure a sign bit |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
932 exists. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
933 unsigned char msb = *(p - pincr); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
934 int sign_bit_set = msb >= 0x80; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
935 assert(accumbits == 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
936 if (sign_bit_set == do_twos_comp) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
937 return 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
938 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
939 goto Overflow; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
940 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
941 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
942 /* Fill remaining bytes with copies of the sign bit. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
943 { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
944 unsigned char signbyte = do_twos_comp ? 0xffU : 0U; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
945 for ( ; j < n; ++j, p += pincr) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
946 *p = signbyte; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
947 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
948 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
949 return 0; |
|
18082
dd09f11fa40d
Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents:
15946
diff
changeset
|
950 |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
951 Overflow: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
952 PyErr_SetString(PyExc_OverflowError, "int too big to convert"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
953 return -1; |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
954 |
|
18082
dd09f11fa40d
Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents:
15946
diff
changeset
|
955 } |
|
dd09f11fa40d
Two new private longobject API functions,
Tim Peters <tim.peters@gmail.com>
parents:
15946
diff
changeset
|
956 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
957 /* Create a new int object from a C pointer */ |
|
9123
17d0c51e0887
Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents:
9094
diff
changeset
|
958 |
|
17d0c51e0887
Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents:
9094
diff
changeset
|
959 PyObject * |
|
13406
a503af7e7fb7
Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents:
13256
diff
changeset
|
960 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
|
961 { |
|
79815
bedb2903d71e
Issue #16277: in PyLong_FromVoidPtr, add missing branch for sizeof(void*) <= sizeof(long).
Mark Dickinson <mdickinson@enthought.com>
parents:
79587
diff
changeset
|
962 #if SIZEOF_VOID_P <= SIZEOF_LONG |
|
bedb2903d71e
Issue #16277: in PyLong_FromVoidPtr, add missing branch for sizeof(void*) <= sizeof(long).
Mark Dickinson <mdickinson@enthought.com>
parents:
79587
diff
changeset
|
963 return PyLong_FromUnsignedLong((unsigned long)(Py_uintptr_t)p); |
|
bedb2903d71e
Issue #16277: in PyLong_FromVoidPtr, add missing branch for sizeof(void*) <= sizeof(long).
Mark Dickinson <mdickinson@enthought.com>
parents:
79587
diff
changeset
|
964 #else |
|
bedb2903d71e
Issue #16277: in PyLong_FromVoidPtr, add missing branch for sizeof(void*) <= sizeof(long).
Mark Dickinson <mdickinson@enthought.com>
parents:
79587
diff
changeset
|
965 |
|
18134
eff8da7c3dcb
PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents:
18121
diff
changeset
|
966 #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
|
967 # 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
|
968 #endif |
|
eff8da7c3dcb
PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents:
18121
diff
changeset
|
969 #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
|
970 # 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
|
971 #endif |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
972 return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)(Py_uintptr_t)p); |
|
79815
bedb2903d71e
Issue #16277: in PyLong_FromVoidPtr, add missing branch for sizeof(void*) <= sizeof(long).
Mark Dickinson <mdickinson@enthought.com>
parents:
79587
diff
changeset
|
973 #endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
974 |
|
9123
17d0c51e0887
Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents:
9094
diff
changeset
|
975 } |
|
17d0c51e0887
Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents:
9094
diff
changeset
|
976 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
977 /* Get a C pointer from an int object. */ |
|
9123
17d0c51e0887
Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents:
9094
diff
changeset
|
978 |
|
17d0c51e0887
Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents:
9094
diff
changeset
|
979 void * |
|
13406
a503af7e7fb7
Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents:
13256
diff
changeset
|
980 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
|
981 { |
|
18134
eff8da7c3dcb
PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents:
18121
diff
changeset
|
982 #if SIZEOF_VOID_P <= SIZEOF_LONG |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
983 long x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
984 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
985 if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
986 x = PyLong_AsLong(vv); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
987 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
988 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
|
989 #else |
|
18134
eff8da7c3dcb
PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents:
18121
diff
changeset
|
990 |
|
eff8da7c3dcb
PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents:
18121
diff
changeset
|
991 #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
|
992 # 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
|
993 #endif |
|
eff8da7c3dcb
PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents:
18121
diff
changeset
|
994 #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
|
995 # 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
|
996 #endif |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
997 PY_LONG_LONG x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
998 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
999 if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1000 x = PyLong_AsLongLong(vv); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1001 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1002 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
|
1003 |
|
eff8da7c3dcb
PyLong_{As, From}VoidPtr: cleanup, replacing assumptions in comments with
Tim Peters <tim.peters@gmail.com>
parents:
18121
diff
changeset
|
1004 #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
|
1005 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1006 if (x == -1 && PyErr_Occurred()) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1007 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1008 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
|
1009 } |
|
17d0c51e0887
Patches from Greg Stein to support 'P' format in struct module's
Guido van Rossum <guido@python.org>
parents:
9094
diff
changeset
|
1010 |
|
8822
bd47ee068b83
Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents:
8808
diff
changeset
|
1011 #ifdef HAVE_LONG_LONG |
| 18093 | 1012 |
|
28437
871da703e4c0
Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents:
28032
diff
changeset
|
1013 /* Initial PY_LONG_LONG support by Chris Herborth (chrish@qnx.com), later |
| 18093 | 1014 * 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
|
1015 */ |
|
bd47ee068b83
Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents:
8808
diff
changeset
|
1016 |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
1017 #define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN) |
| 18093 | 1018 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1019 /* Create a new 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
|
1020 |
|
bd47ee068b83
Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents:
8808
diff
changeset
|
1021 PyObject * |
|
28437
871da703e4c0
Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents:
28032
diff
changeset
|
1022 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
|
1023 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1024 PyLongObject *v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1025 unsigned PY_LONG_LONG abs_ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1026 unsigned PY_LONG_LONG t; /* unsigned so >> doesn't propagate sign bit */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1027 int ndigits = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1028 int negative = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1029 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1030 CHECK_SMALL_INT(ival); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1031 if (ival < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1032 /* avoid signed overflow on negation; see comments |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1033 in PyLong_FromLong above. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1034 abs_ival = (unsigned PY_LONG_LONG)(-1-ival) + 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1035 negative = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1036 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1037 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1038 abs_ival = (unsigned PY_LONG_LONG)ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1039 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1040 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1041 /* Count the number of Python digits. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1042 We used to pick 5 ("big enough for anything"), but that's a |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1043 waste of time and space given that 5*15 = 75 bits are rarely |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1044 needed. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1045 t = abs_ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1046 while (t) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1047 ++ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1048 t >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1049 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1050 v = _PyLong_New(ndigits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1051 if (v != NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1052 digit *p = v->ob_digit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1053 Py_SIZE(v) = negative ? -ndigits : ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1054 t = abs_ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1055 while (t) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1056 *p++ = (digit)(t & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1057 t >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1058 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1059 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1060 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
|
1061 } |
|
bd47ee068b83
Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents:
8808
diff
changeset
|
1062 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1063 /* Create a new int object from a C unsigned PY_LONG_LONG int. */ |
| 18093 | 1064 |
|
8822
bd47ee068b83
Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents:
8808
diff
changeset
|
1065 PyObject * |
|
28437
871da703e4c0
Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents:
28032
diff
changeset
|
1066 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
|
1067 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1068 PyLongObject *v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1069 unsigned PY_LONG_LONG t; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1070 int ndigits = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1071 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1072 if (ival < PyLong_BASE) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1073 return PyLong_FromLong((long)ival); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1074 /* Count the number of Python digits. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1075 t = (unsigned PY_LONG_LONG)ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1076 while (t) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1077 ++ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1078 t >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1079 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1080 v = _PyLong_New(ndigits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1081 if (v != NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1082 digit *p = v->ob_digit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1083 Py_SIZE(v) = ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1084 while (ival) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1085 *p++ = (digit)(ival & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1086 ival >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1087 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1088 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1089 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
|
1090 } |
|
bd47ee068b83
Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents:
8808
diff
changeset
|
1091 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1092 /* Create a new int object from a C Py_ssize_t. */ |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1093 |
|
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1094 PyObject * |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
1095 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
|
1096 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1097 PyLongObject *v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1098 size_t abs_ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1099 size_t t; /* unsigned so >> doesn't propagate sign bit */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1100 int ndigits = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1101 int negative = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1102 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1103 CHECK_SMALL_INT(ival); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1104 if (ival < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1105 /* avoid signed overflow when ival = SIZE_T_MIN */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1106 abs_ival = (size_t)(-1-ival)+1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1107 negative = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1108 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1109 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1110 abs_ival = (size_t)ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1111 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1112 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1113 /* Count the number of Python digits. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1114 t = abs_ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1115 while (t) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1116 ++ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1117 t >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1118 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1119 v = _PyLong_New(ndigits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1120 if (v != NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1121 digit *p = v->ob_digit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1122 Py_SIZE(v) = negative ? -ndigits : ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1123 t = abs_ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1124 while (t) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1125 *p++ = (digit)(t & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1126 t >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1127 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1128 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1129 return (PyObject *)v; |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1130 } |
|
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1131 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1132 /* Create a new int object from a C size_t. */ |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1133 |
|
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1134 PyObject * |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
1135 PyLong_FromSize_t(size_t ival) |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1136 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1137 PyLongObject *v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1138 size_t t; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1139 int ndigits = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1140 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1141 if (ival < PyLong_BASE) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1142 return PyLong_FromLong((long)ival); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1143 /* Count the number of Python digits. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1144 t = ival; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1145 while (t) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1146 ++ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1147 t >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1148 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1149 v = _PyLong_New(ndigits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1150 if (v != NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1151 digit *p = v->ob_digit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1152 Py_SIZE(v) = ndigits; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1153 while (ival) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1154 *p++ = (digit)(ival & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1155 ival >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1156 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1157 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1158 return (PyObject *)v; |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1159 } |
|
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1160 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1161 /* Get a C long long int from an int object or any object that has an |
|
73075
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
1162 __int__ method. 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
|
1163 |
|
28437
871da703e4c0
Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents:
28032
diff
changeset
|
1164 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
|
1165 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
|
1166 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1167 PyLongObject *v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1168 PY_LONG_LONG bytes; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1169 int res; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1170 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1171 if (vv == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1172 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1173 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1174 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1175 if (!PyLong_Check(vv)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1176 PyNumberMethods *nb; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1177 PyObject *io; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1178 if ((nb = vv->ob_type->tp_as_number) == NULL || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1179 nb->nb_int == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1180 PyErr_SetString(PyExc_TypeError, "an integer is required"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1181 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1182 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1183 io = (*nb->nb_int) (vv); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1184 if (io == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1185 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1186 if (PyLong_Check(io)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1187 bytes = PyLong_AsLongLong(io); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1188 Py_DECREF(io); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1189 return bytes; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1190 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1191 Py_DECREF(io); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1192 PyErr_SetString(PyExc_TypeError, "integer conversion failed"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1193 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1194 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1195 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1196 v = (PyLongObject*)vv; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1197 switch(Py_SIZE(v)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1198 case -1: return -(sdigit)v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1199 case 0: return 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1200 case 1: return v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1201 } |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
1202 res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, |
|
79803
d2127cdec10e
Issue #16166: Add PY_LITTLE_ENDIAN and PY_BIG_ENDIAN macros and unified
Christian Heimes <christian@cheimes.de>
parents:
79589
diff
changeset
|
1203 SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 1); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1204 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1205 /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1206 if (res < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1207 return (PY_LONG_LONG)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1208 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1209 return bytes; |
| 18093 | 1210 } |
|
8822
bd47ee068b83
Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents:
8808
diff
changeset
|
1211 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1212 /* Get a C unsigned PY_LONG_LONG int from an int object. |
| 18093 | 1213 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
|
1214 |
|
28437
871da703e4c0
Rename LONG_LONG to PY_LONG_LONG. Fixes #710285.
Martin v. Löwis <martin@v.loewis.de>
parents:
28032
diff
changeset
|
1215 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
|
1216 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
|
1217 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1218 PyLongObject *v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1219 unsigned PY_LONG_LONG bytes; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1220 int res; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1221 |
|
72312
4a66a35da3fd
Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.
Nadeem Vawda <nadeem.vawda@gmail.com>
parents:
71810
diff
changeset
|
1222 if (vv == NULL) { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1223 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1224 return (unsigned PY_LONG_LONG)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1225 } |
|
72312
4a66a35da3fd
Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.
Nadeem Vawda <nadeem.vawda@gmail.com>
parents:
71810
diff
changeset
|
1226 if (!PyLong_Check(vv)) { |
|
4a66a35da3fd
Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.
Nadeem Vawda <nadeem.vawda@gmail.com>
parents:
71810
diff
changeset
|
1227 PyErr_SetString(PyExc_TypeError, "an integer is required"); |
|
4a66a35da3fd
Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.
Nadeem Vawda <nadeem.vawda@gmail.com>
parents:
71810
diff
changeset
|
1228 return (unsigned PY_LONG_LONG)-1; |
|
4a66a35da3fd
Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.
Nadeem Vawda <nadeem.vawda@gmail.com>
parents:
71810
diff
changeset
|
1229 } |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1230 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1231 v = (PyLongObject*)vv; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1232 switch(Py_SIZE(v)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1233 case 0: return 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1234 case 1: return v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1235 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1236 |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
1237 res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, |
|
79803
d2127cdec10e
Issue #16166: Add PY_LITTLE_ENDIAN and PY_BIG_ENDIAN macros and unified
Christian Heimes <christian@cheimes.de>
parents:
79589
diff
changeset
|
1238 SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 0); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1239 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1240 /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1241 if (res < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1242 return (unsigned PY_LONG_LONG)res; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1243 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1244 return bytes; |
| 18093 | 1245 } |
|
8822
bd47ee068b83
Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents:
8808
diff
changeset
|
1246 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1247 /* Get a C unsigned long int from an int object, ignoring the high bits. |
|
28652
28a2975514cd
SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents:
28437
diff
changeset
|
1248 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
|
1249 |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
1250 static unsigned PY_LONG_LONG |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
1251 _PyLong_AsUnsignedLongLongMask(PyObject *vv) |
|
28652
28a2975514cd
SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents:
28437
diff
changeset
|
1252 { |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
1253 PyLongObject *v; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1254 unsigned PY_LONG_LONG x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1255 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1256 int sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1257 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1258 if (vv == NULL || !PyLong_Check(vv)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1259 PyErr_BadInternalCall(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1260 return (unsigned long) -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1261 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1262 v = (PyLongObject *)vv; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1263 switch(Py_SIZE(v)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1264 case 0: return 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1265 case 1: return v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1266 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1267 i = Py_SIZE(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1268 sign = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1269 x = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1270 if (i < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1271 sign = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1272 i = -i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1273 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1274 while (--i >= 0) { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1275 x = (x << PyLong_SHIFT) | v->ob_digit[i]; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1276 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1277 return x * sign; |
|
28652
28a2975514cd
SF # 595026: support for masks in getargs.c.
Thomas Heller <theller@ctypes.org>
parents:
28437
diff
changeset
|
1278 } |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
1279 |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
1280 unsigned PY_LONG_LONG |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
1281 PyLong_AsUnsignedLongLongMask(PyObject *op) |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
1282 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1283 PyNumberMethods *nb; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1284 PyLongObject *lo; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1285 unsigned PY_LONG_LONG val; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1286 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1287 if (op && PyLong_Check(op)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1288 return _PyLong_AsUnsignedLongLongMask(op); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1289 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1290 if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1291 nb->nb_int == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1292 PyErr_SetString(PyExc_TypeError, "an integer is required"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1293 return (unsigned PY_LONG_LONG)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1294 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1295 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1296 lo = (PyLongObject*) (*nb->nb_int) (op); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1297 if (lo == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1298 return (unsigned PY_LONG_LONG)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1299 if (PyLong_Check(lo)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1300 val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1301 Py_DECREF(lo); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1302 if (PyErr_Occurred()) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1303 return (unsigned PY_LONG_LONG)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1304 return val; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1305 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1306 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1307 { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1308 Py_DECREF(lo); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1309 PyErr_SetString(PyExc_TypeError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1310 "nb_int should return int object"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1311 return (unsigned PY_LONG_LONG)-1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1312 } |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
1313 } |
| 18093 | 1314 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1315 /* Get a C long long int from an int object or any object that has an |
|
73075
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
1316 __int__ method. |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
1317 |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
1318 On overflow, return -1 and set *overflow to 1 or -1 depending on the sign of |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
1319 the result. Otherwise *overflow is 0. |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
1320 |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
1321 For other errors (e.g., TypeError), return -1 and set an error condition. |
|
d4839fea4a5a
Issue #12965: Fix some inaccurate comments in Objects/longobject.c. Thanks Stefan Krah.
Mark Dickinson <mdickinson@enthought.com>
parents:
72510
diff
changeset
|
1322 In this case *overflow will be 0. |
|
58582
5893ef9a9b84
Merged revisions 77842 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58225
diff
changeset
|
1323 */ |
|
5893ef9a9b84
Merged revisions 77842 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58225
diff
changeset
|
1324 |
|
5893ef9a9b84
Merged revisions 77842 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58225
diff
changeset
|
1325 PY_LONG_LONG |
|
5893ef9a9b84
Merged revisions 77842 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58225
diff
changeset
|
1326 PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) |
|
5893ef9a9b84
Merged revisions 77842 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58225
diff
changeset
|
1327 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1328 /* This version by Tim Peters */ |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
1329 PyLongObject *v; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1330 unsigned PY_LONG_LONG x, prev; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1331 PY_LONG_LONG res; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1332 Py_ssize_t i; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1333 int sign; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1334 int do_decref = 0; /* if nb_int was called */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1335 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1336 *overflow = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1337 if (vv == NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1338 PyErr_BadInternalCall(); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1339 return -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1340 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1341 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1342 if (!PyLong_Check(vv)) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1343 PyNumberMethods *nb; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1344 nb = vv->ob_type->tp_as_number; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1345 if (nb == NULL || nb->nb_int == NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1346 PyErr_SetString(PyExc_TypeError, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1347 "an integer is required"); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1348 return -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1349 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1350 vv = (*nb->nb_int) (vv); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1351 if (vv == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1352 return -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1353 do_decref = 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1354 if (!PyLong_Check(vv)) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1355 Py_DECREF(vv); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1356 PyErr_SetString(PyExc_TypeError, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1357 "nb_int should return int object"); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1358 return -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1359 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1360 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1361 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1362 res = -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1363 v = (PyLongObject *)vv; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1364 i = Py_SIZE(v); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1365 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1366 switch (i) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1367 case -1: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1368 res = -(sdigit)v->ob_digit[0]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1369 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1370 case 0: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1371 res = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1372 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1373 case 1: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1374 res = v->ob_digit[0]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1375 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1376 default: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1377 sign = 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1378 x = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1379 if (i < 0) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1380 sign = -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1381 i = -(i); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1382 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1383 while (--i >= 0) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1384 prev = x; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1385 x = (x << PyLong_SHIFT) + v->ob_digit[i]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1386 if ((x >> PyLong_SHIFT) != prev) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1387 *overflow = sign; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1388 goto exit; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1389 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1390 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1391 /* Haven't lost any bits, but casting to long requires extra |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1392 * care (see comment above). |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1393 */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1394 if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1395 res = (PY_LONG_LONG)x * sign; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1396 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1397 else if (sign < 0 && x == PY_ABS_LLONG_MIN) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1398 res = PY_LLONG_MIN; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1399 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1400 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1401 *overflow = sign; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1402 /* res is already set to -1 */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1403 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1404 } |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
1405 exit: |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1406 if (do_decref) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1407 Py_DECREF(vv); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1408 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1409 return res; |
|
58582
5893ef9a9b84
Merged revisions 77842 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58225
diff
changeset
|
1410 } |
|
5893ef9a9b84
Merged revisions 77842 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58225
diff
changeset
|
1411 |
|
8822
bd47ee068b83
Changes for BeOS, QNX and long long, by Chris Herborth.
Guido van Rossum <guido@python.org>
parents:
8808
diff
changeset
|
1412 #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
|
1413 |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
1414 #define CHECK_BINOP(v,w) \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
1415 do { \ |
|
71810
d0b0fcbb40db
Replace Py_NotImplemented returns with the macro form Py_RETURN_NOTIMPLEMENTED.
Brian Curtin <brian@python.org>
parents:
68586
diff
changeset
|
1416 if (!PyLong_Check(v) || !PyLong_Check(w)) \ |
|
d0b0fcbb40db
Replace Py_NotImplemented returns with the macro form Py_RETURN_NOTIMPLEMENTED.
Brian Curtin <brian@python.org>
parents:
68586
diff
changeset
|
1417 Py_RETURN_NOTIMPLEMENTED; \ |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
1418 } 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
|
1419 |
|
52289
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1420 /* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d < |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1421 2**k if d is nonzero, else 0. */ |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1422 |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1423 static const unsigned char BitLengthTable[32] = { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1424 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1425 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 |
|
52289
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1426 }; |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1427 |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1428 static int |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1429 bits_in_digit(digit d) |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1430 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1431 int d_bits = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1432 while (d >= 32) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1433 d_bits += 6; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1434 d >>= 6; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1435 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1436 d_bits += (int)BitLengthTable[d]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1437 return d_bits; |
|
52289
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1438 } |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1439 |
|
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
|
1440 /* 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
|
1441 * 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
|
1442 * 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
|
1443 */ |
|
c248bee52dc6
Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents:
24747
diff
changeset
|
1444 static digit |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1445 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
|
1446 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1447 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1448 digit carry = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1449 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1450 assert(m >= n); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1451 for (i = 0; i < n; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1452 carry += x[i] + y[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1453 x[i] = carry & PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1454 carry >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1455 assert((carry & 1) == carry); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1456 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1457 for (; carry && i < m; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1458 carry += x[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1459 x[i] = carry & PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1460 carry >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1461 assert((carry & 1) == carry); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1462 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1463 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
|
1464 } |
|
c248bee52dc6
Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents:
24747
diff
changeset
|
1465 |
|
c248bee52dc6
Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents:
24747
diff
changeset
|
1466 /* 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
|
1467 * 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
|
1468 * 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
|
1469 */ |
|
c248bee52dc6
Introduced helper functions v_iadd and v_isub, for in-place digit-vector
Tim Peters <tim.peters@gmail.com>
parents:
24747
diff
changeset
|
1470 static digit |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1471 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
|
1472 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1473 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1474 digit borrow = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1475 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1476 assert(m >= n); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1477 for (i = 0; i < n; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1478 borrow = x[i] - y[i] - borrow; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1479 x[i] = borrow & PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1480 borrow >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1481 borrow &= 1; /* keep only 1 sign bit */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1482 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1483 for (; borrow && i < m; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1484 borrow = x[i] - borrow; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1485 x[i] = borrow & PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1486 borrow >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1487 borrow &= 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1488 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1489 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
|
1490 } |
|
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
|
1491 |
|
52289
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1492 /* Shift digit vector a[0:m] d bits left, with 0 <= d < PyLong_SHIFT. Put |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1493 * result in z[0:m], and return the d bits shifted out of the top. |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1494 */ |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1495 static digit |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1496 v_lshift(digit *z, digit *a, Py_ssize_t m, int d) |
| 230 | 1497 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1498 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1499 digit carry = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1500 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1501 assert(0 <= d && d < PyLong_SHIFT); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1502 for (i=0; i < m; i++) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1503 twodigits acc = (twodigits)a[i] << d | carry; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1504 z[i] = (digit)acc & PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1505 carry = (digit)(acc >> PyLong_SHIFT); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1506 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1507 return carry; |
|
52289
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1508 } |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1509 |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1510 /* Shift digit vector a[0:m] d bits right, with 0 <= d < PyLong_SHIFT. Put |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1511 * result in z[0:m], and return the d bits shifted out of the bottom. |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1512 */ |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1513 static digit |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1514 v_rshift(digit *z, digit *a, Py_ssize_t m, int d) |
|
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
1515 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1516 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1517 digit carry = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1518 digit mask = ((digit)1 << d) - 1U; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1519 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1520 assert(0 <= d && d < PyLong_SHIFT); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1521 for (i=m; i-- > 0;) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1522 twodigits acc = (twodigits)carry << PyLong_SHIFT | a[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1523 carry = (digit)acc & mask; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1524 z[i] = (digit)(acc >> d); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1525 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1526 return carry; |
| 230 | 1527 } |
| 1528 | |
|
18594
19250f9181dc
divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents:
18593
diff
changeset
|
1529 /* 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
|
1530 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
|
1531 It's OK for pin == pout on entry, which saves oodles of mallocs/frees in |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1532 _PyLong_Format, but that should be done with great care since ints 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
|
1533 immutable. */ |
|
19250f9181dc
divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents:
18593
diff
changeset
|
1534 |
|
19250f9181dc
divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents:
18593
diff
changeset
|
1535 static digit |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
1536 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
|
1537 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1538 twodigits rem = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1539 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1540 assert(n > 0 && n <= PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1541 pin += size; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1542 pout += size; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1543 while (--size >= 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1544 digit hi; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1545 rem = (rem << PyLong_SHIFT) | *--pin; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1546 *--pout = hi = (digit)(rem / n); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1547 rem -= (twodigits)hi * n; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1548 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1549 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
|
1550 } |
|
19250f9181dc
divrem1 & long_format: found a clean way to factor divrem1 so that
Tim Peters <tim.peters@gmail.com>
parents:
18593
diff
changeset
|
1551 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1552 /* Divide an integer by a digit, returning both the quotient |
| 230 | 1553 (as function result) and the remainder (through *prem). |
| 1554 The sign of a is ignored; n should not be zero. */ | |
| 1555 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
1556 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
|
1557 divrem1(PyLongObject *a, digit n, digit *prem) |
| 230 | 1558 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1559 const Py_ssize_t size = ABS(Py_SIZE(a)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1560 PyLongObject *z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1561 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1562 assert(n > 0 && n <= PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1563 z = _PyLong_New(size); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1564 if (z == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1565 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1566 *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1567 return long_normalize(z); |
| 230 | 1568 } |
| 1569 | |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1570 /* Convert an integer to a base 10 string. Returns a new non-shared |
|
56017
1e09dc68c8f3
Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents:
55938
diff
changeset
|
1571 string. (Return value is non-shared so that callers can modify the |
|
1e09dc68c8f3
Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents:
55938
diff
changeset
|
1572 returned value if necessary.) */ |
|
1e09dc68c8f3
Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents:
55938
diff
changeset
|
1573 |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1574 static int |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1575 long_to_decimal_string_internal(PyObject *aa, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1576 PyObject **p_output, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1577 _PyUnicodeWriter *writer) |
|
56017
1e09dc68c8f3
Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents:
55938
diff
changeset
|
1578 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1579 PyLongObject *scratch, *a; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1580 PyObject *str; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1581 Py_ssize_t size, strlen, size_a, i, j; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1582 digit *pout, *pin, rem, tenpow; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1583 int negative; |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1584 enum PyUnicode_Kind kind; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1585 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1586 a = (PyLongObject *)aa; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1587 if (a == NULL || !PyLong_Check(a)) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1588 PyErr_BadInternalCall(); |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1589 return -1; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1590 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1591 size_a = ABS(Py_SIZE(a)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1592 negative = Py_SIZE(a) < 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1593 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1594 /* quick and dirty upper bound for the number of digits |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1595 required to express a in base _PyLong_DECIMAL_BASE: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1596 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1597 #digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE)) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1598 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1599 But log2(a) < size_a * PyLong_SHIFT, and |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1600 log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1601 > 3 * _PyLong_DECIMAL_SHIFT |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1602 */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1603 if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1604 PyErr_SetString(PyExc_OverflowError, |
|
84983
dab7d6f33b87
Minor consistency fixes for some longobject.c exception messages:
Mark Dickinson <dickinsm@gmail.com>
parents:
84793
diff
changeset
|
1605 "int too large to format"); |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1606 return -1; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1607 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1608 /* the expression size_a * PyLong_SHIFT is now safe from overflow */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1609 size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1610 scratch = _PyLong_New(size); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1611 if (scratch == NULL) |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1612 return -1; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1613 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1614 /* convert array of base _PyLong_BASE digits in pin to an array of |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1615 base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1616 Volume 2 (3rd edn), section 4.4, Method 1b). */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1617 pin = a->ob_digit; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1618 pout = scratch->ob_digit; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1619 size = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1620 for (i = size_a; --i >= 0; ) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1621 digit hi = pin[i]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1622 for (j = 0; j < size; j++) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1623 twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1624 hi = (digit)(z / _PyLong_DECIMAL_BASE); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1625 pout[j] = (digit)(z - (twodigits)hi * |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1626 _PyLong_DECIMAL_BASE); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1627 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1628 while (hi) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1629 pout[size++] = hi % _PyLong_DECIMAL_BASE; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1630 hi /= _PyLong_DECIMAL_BASE; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1631 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1632 /* check for keyboard interrupt */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1633 SIGCHECK({ |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
1634 Py_DECREF(scratch); |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1635 return -1; |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
1636 }); |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1637 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1638 /* pout should have at least one digit, so that the case when a = 0 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1639 works correctly */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1640 if (size == 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1641 pout[size++] = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1642 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1643 /* calculate exact length of output string, and allocate */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1644 strlen = negative + 1 + (size - 1) * _PyLong_DECIMAL_SHIFT; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1645 tenpow = 10; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1646 rem = pout[size-1]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1647 while (rem >= tenpow) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1648 tenpow *= 10; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1649 strlen++; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1650 } |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1651 if (writer) { |
|
78936
1349e9537f91
Fixed resource leak to scratch when _PyUnicodeWriter_Prepare fails
Christian Heimes <christian@cheimes.de>
parents:
77230
diff
changeset
|
1652 if (_PyUnicodeWriter_Prepare(writer, strlen, '9') == -1) { |
|
1349e9537f91
Fixed resource leak to scratch when _PyUnicodeWriter_Prepare fails
Christian Heimes <christian@cheimes.de>
parents:
77230
diff
changeset
|
1653 Py_DECREF(scratch); |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1654 return -1; |
|
78936
1349e9537f91
Fixed resource leak to scratch when _PyUnicodeWriter_Prepare fails
Christian Heimes <christian@cheimes.de>
parents:
77230
diff
changeset
|
1655 } |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1656 kind = writer->kind; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1657 str = NULL; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1658 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1659 else { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1660 str = PyUnicode_New(strlen, '9'); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1661 if (str == NULL) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1662 Py_DECREF(scratch); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1663 return -1; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1664 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1665 kind = PyUnicode_KIND(str); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1666 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1667 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1668 #define WRITE_DIGITS(TYPE) \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1669 do { \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1670 if (writer) \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1671 p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + strlen; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1672 else \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1673 p = (TYPE*)PyUnicode_DATA(str) + strlen; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1674 \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1675 /* pout[0] through pout[size-2] contribute exactly \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1676 _PyLong_DECIMAL_SHIFT digits each */ \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1677 for (i=0; i < size - 1; i++) { \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1678 rem = pout[i]; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1679 for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) { \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1680 *--p = '0' + rem % 10; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1681 rem /= 10; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1682 } \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1683 } \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1684 /* pout[size-1]: always produce at least one decimal digit */ \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1685 rem = pout[i]; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1686 do { \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1687 *--p = '0' + rem % 10; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1688 rem /= 10; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1689 } while (rem != 0); \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1690 \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1691 /* and sign */ \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1692 if (negative) \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1693 *--p = '-'; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1694 \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1695 /* check we've counted correctly */ \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1696 if (writer) \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1697 assert(p == ((TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos)); \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1698 else \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1699 assert(p == (TYPE*)PyUnicode_DATA(str)); \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1700 } while (0) |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1701 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1702 /* fill the string right-to-left */ |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1703 if (kind == PyUnicode_1BYTE_KIND) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1704 Py_UCS1 *p; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1705 WRITE_DIGITS(Py_UCS1); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1706 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1707 else if (kind == PyUnicode_2BYTE_KIND) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1708 Py_UCS2 *p; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1709 WRITE_DIGITS(Py_UCS2); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1710 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1711 else { |
|
77230
6abab1a103a6
Issue #14744: Fix compilation on Windows
Victor Stinner <victor.stinner@gmail.com>
parents:
77223
diff
changeset
|
1712 Py_UCS4 *p; |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1713 assert (kind == PyUnicode_4BYTE_KIND); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1714 WRITE_DIGITS(Py_UCS4); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1715 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1716 #undef WRITE_DIGITS |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1717 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1718 Py_DECREF(scratch); |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1719 if (writer) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1720 writer->pos += strlen; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1721 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1722 else { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1723 assert(_PyUnicode_CheckConsistency(str, 1)); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1724 *p_output = (PyObject *)str; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1725 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1726 return 0; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1727 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1728 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1729 static PyObject * |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1730 long_to_decimal_string(PyObject *aa) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1731 { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1732 PyObject *v; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1733 if (long_to_decimal_string_internal(aa, &v, NULL) == -1) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1734 return NULL; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1735 return v; |
|
56017
1e09dc68c8f3
Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents:
55938
diff
changeset
|
1736 } |
|
1e09dc68c8f3
Issue #6713: Improve performance of str(n) and repr(n) for integers n
Mark Dickinson <dickinsm@gmail.com>
parents:
55938
diff
changeset
|
1737 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1738 /* Convert an int object to a string, using a given conversion base, |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1739 which should be one of 2, 8 or 16. Return a string object. |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1740 If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x' |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1741 if alternate is nonzero. */ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1742 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1743 static int |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1744 long_format_binary(PyObject *aa, int base, int alternate, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1745 PyObject **p_output, _PyUnicodeWriter *writer) |
| 230 | 1746 { |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
1747 PyLongObject *a = (PyLongObject *)aa; |
| 72475 | 1748 PyObject *v; |
|
76439
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1749 Py_ssize_t sz; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1750 Py_ssize_t size_a; |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1751 enum PyUnicode_Kind kind; |
|
76439
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1752 int negative; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1753 int bits; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1754 |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1755 assert(base == 2 || base == 8 || base == 16); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1756 if (a == NULL || !PyLong_Check(a)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1757 PyErr_BadInternalCall(); |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1758 return -1; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1759 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1760 size_a = ABS(Py_SIZE(a)); |
|
76439
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1761 negative = Py_SIZE(a) < 0; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1762 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1763 /* Compute a rough upper bound for the length of the string */ |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1764 switch (base) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1765 case 16: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1766 bits = 4; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1767 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1768 case 8: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1769 bits = 3; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1770 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1771 case 2: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1772 bits = 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1773 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1774 default: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1775 assert(0); /* shouldn't ever get here */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1776 bits = 0; /* to silence gcc warning */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1777 } |
|
76439
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1778 |
|
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1779 /* Compute exact length 'sz' of output string. */ |
|
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1780 if (size_a == 0) { |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1781 sz = 1; |
|
76439
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1782 } |
|
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1783 else { |
|
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1784 Py_ssize_t size_a_in_bits; |
|
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1785 /* Ensure overflow doesn't occur during computation of sz. */ |
|
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1786 if (size_a > (PY_SSIZE_T_MAX - 3) / PyLong_SHIFT) { |
|
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1787 PyErr_SetString(PyExc_OverflowError, |
|
84983
dab7d6f33b87
Minor consistency fixes for some longobject.c exception messages:
Mark Dickinson <dickinsm@gmail.com>
parents:
84793
diff
changeset
|
1788 "int too large to format"); |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1789 return -1; |
|
76439
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1790 } |
|
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1791 size_a_in_bits = (size_a - 1) * PyLong_SHIFT + |
|
dcd3344b6d5b
Issue #14339: Improve speed of bin, oct and hex builtins. Patch by Serhiy Storchaka (with minor modifications).
Mark Dickinson <mdickinson@enthought.com>
parents:
73075
diff
changeset
|
1792 bits_in_digit(a->ob_digit[size_a - 1]); |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1793 /* Allow 1 character for a '-' sign. */ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1794 sz = negative + (size_a_in_bits + (bits - 1)) / bits; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1795 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1796 if (alternate) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1797 /* 2 characters for prefix */ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1798 sz += 2; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1799 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1800 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1801 if (writer) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1802 if (_PyUnicodeWriter_Prepare(writer, sz, 'x') == -1) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1803 return -1; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1804 kind = writer->kind; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1805 v = NULL; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1806 } |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
1807 else { |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1808 v = PyUnicode_New(sz, 'x'); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1809 if (v == NULL) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1810 return -1; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1811 kind = PyUnicode_KIND(v); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1812 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1813 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1814 #define WRITE_DIGITS(TYPE) \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1815 do { \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1816 if (writer) \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1817 p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + sz; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1818 else \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1819 p = (TYPE*)PyUnicode_DATA(v) + sz; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1820 \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1821 if (size_a == 0) { \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1822 *--p = '0'; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1823 } \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1824 else { \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1825 /* JRH: special case for power-of-2 bases */ \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1826 twodigits accum = 0; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1827 int accumbits = 0; /* # of bits in accum */ \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1828 Py_ssize_t i; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1829 for (i = 0; i < size_a; ++i) { \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1830 accum |= (twodigits)a->ob_digit[i] << accumbits; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1831 accumbits += PyLong_SHIFT; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1832 assert(accumbits >= bits); \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1833 do { \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1834 char cdigit; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1835 cdigit = (char)(accum & (base - 1)); \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1836 cdigit += (cdigit < 10) ? '0' : 'a'-10; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1837 *--p = cdigit; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1838 accumbits -= bits; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1839 accum >>= bits; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1840 } while (i < size_a-1 ? accumbits >= bits : accum > 0); \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1841 } \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1842 } \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1843 \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1844 if (alternate) { \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1845 if (base == 16) \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1846 *--p = 'x'; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1847 else if (base == 8) \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1848 *--p = 'o'; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1849 else /* (base == 2) */ \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1850 *--p = 'b'; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1851 *--p = '0'; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1852 } \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1853 if (negative) \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1854 *--p = '-'; \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1855 if (writer) \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1856 assert(p == ((TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos)); \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1857 else \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1858 assert(p == (TYPE*)PyUnicode_DATA(v)); \ |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1859 } while (0) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1860 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1861 if (kind == PyUnicode_1BYTE_KIND) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1862 Py_UCS1 *p; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1863 WRITE_DIGITS(Py_UCS1); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1864 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1865 else if (kind == PyUnicode_2BYTE_KIND) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1866 Py_UCS2 *p; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1867 WRITE_DIGITS(Py_UCS2); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1868 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1869 else { |
|
77230
6abab1a103a6
Issue #14744: Fix compilation on Windows
Victor Stinner <victor.stinner@gmail.com>
parents:
77223
diff
changeset
|
1870 Py_UCS4 *p; |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1871 assert (kind == PyUnicode_4BYTE_KIND); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1872 WRITE_DIGITS(Py_UCS4); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1873 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1874 #undef WRITE_DIGITS |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1875 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1876 if (writer) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1877 writer->pos += sz; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1878 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1879 else { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1880 assert(_PyUnicode_CheckConsistency(v, 1)); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1881 *p_output = v; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1882 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1883 return 0; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1884 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1885 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1886 PyObject * |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1887 _PyLong_Format(PyObject *obj, int base) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1888 { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1889 PyObject *str; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1890 int err; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1891 if (base == 10) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1892 err = long_to_decimal_string_internal(obj, &str, NULL); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1893 else |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1894 err = long_format_binary(obj, base, 1, &str, NULL); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1895 if (err == -1) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1896 return NULL; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1897 return str; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1898 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1899 |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1900 int |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1901 _PyLong_FormatWriter(_PyUnicodeWriter *writer, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1902 PyObject *obj, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1903 int base, int alternate) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1904 { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1905 if (base == 10) |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1906 return long_to_decimal_string_internal(obj, NULL, writer); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1907 else |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
1908 return long_format_binary(obj, base, alternate, NULL, writer); |
| 230 | 1909 } |
| 1910 | |
|
38453
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
1911 /* Table of digit values for 8-bit string -> integer conversion. |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
1912 * '0' maps to 0, ..., '9' maps to 9. |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
1913 * 'a' and 'A' map to 10, ..., 'z' and 'Z' map to 35. |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
1914 * All other indices map to 37. |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
1915 * Note that when converting a base B string, a char c is a legitimate |
|
42334
e70cdce0e8b2
Merged revisions 56467-56482 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
42110
diff
changeset
|
1916 * base B digit iff _PyLong_DigitValue[Py_CHARPyLong_MASK(c)] < B. |
|
38453
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
1917 */ |
|
50656
c7c344b63ecc
Reduce the size of the _PyLong_DigitValue table.
Raymond Hettinger <python@rcn.com>
parents:
50241
diff
changeset
|
1918 unsigned char _PyLong_DigitValue[256] = { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1919 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1920 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1921 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1922 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 37, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1923 37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1924 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1925 37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1926 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1927 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1928 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1929 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1930 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1931 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1932 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1933 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1934 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, |
|
38453
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
1935 }; |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
1936 |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
1937 /* *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
|
1938 * is a power of 2 (2, 4, 8, 16, or 32). *str is set to point to the first |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1939 * non-digit (which may be *str!). A normalized int is returned. |
|
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
|
1940 * 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
|
1941 * 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
|
1942 */ |
|
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
|
1943 static PyLongObject * |
|
86484
3055e61f1e66
Issue #1772673: The type of `char*` arguments now changed to `const char*`.
Serhiy Storchaka <storchaka@gmail.com>
parents:
85982
diff
changeset
|
1944 long_from_binary_base(const char **str, int 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
|
1945 { |
|
86484
3055e61f1e66
Issue #1772673: The type of `char*` arguments now changed to `const char*`.
Serhiy Storchaka <storchaka@gmail.com>
parents:
85982
diff
changeset
|
1946 const char *p = *str; |
|
3055e61f1e66
Issue #1772673: The type of `char*` arguments now changed to `const char*`.
Serhiy Storchaka <storchaka@gmail.com>
parents:
85982
diff
changeset
|
1947 const char *start = p; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1948 int bits_per_char; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1949 Py_ssize_t n; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1950 PyLongObject *z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1951 twodigits accum; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1952 int bits_in_accum; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1953 digit *pdigit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1954 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1955 assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1956 n = base; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1957 for (bits_per_char = -1; n; ++bits_per_char) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1958 n >>= 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1959 /* n <- total # of bits needed, while setting p to end-of-string */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1960 while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1961 ++p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1962 *str = p; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1963 /* n <- # of Python digits needed, = ceiling(n/PyLong_SHIFT). */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1964 n = (p - start) * bits_per_char + PyLong_SHIFT - 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1965 if (n / bits_per_char < p - start) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1966 PyErr_SetString(PyExc_ValueError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1967 "int string too large to convert"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1968 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1969 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1970 n = n / PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1971 z = _PyLong_New(n); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1972 if (z == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1973 return NULL; |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
1974 /* Read string from right, and fill in int from left; i.e., |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1975 * from least to most significant in both. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1976 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1977 accum = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1978 bits_in_accum = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1979 pdigit = z->ob_digit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1980 while (--p >= start) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1981 int k = (int)_PyLong_DigitValue[Py_CHARMASK(*p)]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1982 assert(k >= 0 && k < base); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1983 accum |= (twodigits)k << bits_in_accum; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1984 bits_in_accum += bits_per_char; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1985 if (bits_in_accum >= PyLong_SHIFT) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1986 *pdigit++ = (digit)(accum & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1987 assert(pdigit - z->ob_digit <= n); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1988 accum >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1989 bits_in_accum -= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1990 assert(bits_in_accum < PyLong_SHIFT); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1991 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1992 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1993 if (bits_in_accum) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1994 assert(bits_in_accum <= PyLong_SHIFT); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1995 *pdigit++ = (digit)accum; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1996 assert(pdigit - z->ob_digit <= n); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1997 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1998 while (pdigit - z->ob_digit < n) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
1999 *pdigit++ = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2000 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
|
2001 } |
|
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
|
2002 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
2003 /* Parses an int from a bytestring. Leading and trailing whitespace will be |
|
84995
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2004 * ignored. |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2005 * |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2006 * If successful, a PyLong object will be returned and 'pend' will be pointing |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2007 * to the first unused byte unless it's NULL. |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2008 * |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2009 * If unsuccessful, NULL will be returned. |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2010 */ |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
2011 PyObject * |
|
86484
3055e61f1e66
Issue #1772673: The type of `char*` arguments now changed to `const char*`.
Serhiy Storchaka <storchaka@gmail.com>
parents:
85982
diff
changeset
|
2012 PyLong_FromString(const 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
|
2013 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2014 int sign = 1, error_if_nonzero = 0; |
|
86484
3055e61f1e66
Issue #1772673: The type of `char*` arguments now changed to `const char*`.
Serhiy Storchaka <storchaka@gmail.com>
parents:
85982
diff
changeset
|
2015 const char *start, *orig_str = str; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2016 PyLongObject *z = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2017 PyObject *strobj; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2018 Py_ssize_t slen; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2019 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2020 if ((base != 0 && base < 2) || base > 36) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2021 PyErr_SetString(PyExc_ValueError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2022 "int() arg 2 must be >= 2 and <= 36"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2023 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2024 } |
|
82110
38830281d43b
Issue #17173: Remove uses of locale-dependent C functions (isalpha() etc.) in the interpreter.
Antoine Pitrou <solipsis@pitrou.net>
parents:
81587
diff
changeset
|
2025 while (*str != '\0' && Py_ISSPACE(Py_CHARMASK(*str))) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2026 str++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2027 if (*str == '+') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2028 ++str; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2029 else if (*str == '-') { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2030 ++str; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2031 sign = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2032 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2033 if (base == 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2034 if (str[0] != '0') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2035 base = 10; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2036 else if (str[1] == 'x' || str[1] == 'X') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2037 base = 16; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2038 else if (str[1] == 'o' || str[1] == 'O') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2039 base = 8; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2040 else if (str[1] == 'b' || str[1] == 'B') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2041 base = 2; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2042 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2043 /* "old" (C-style) octal literal, now invalid. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2044 it might still be zero though */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2045 error_if_nonzero = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2046 base = 10; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2047 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2048 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2049 if (str[0] == '0' && |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2050 ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2051 (base == 8 && (str[1] == 'o' || str[1] == 'O')) || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2052 (base == 2 && (str[1] == 'b' || str[1] == 'B')))) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2053 str += 2; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2054 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2055 start = str; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2056 if ((base & (base - 1)) == 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2057 z = long_from_binary_base(&str, base); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2058 else { |
|
38453
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2059 /*** |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2060 Binary bases can be converted in time linear in the number of digits, because |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2061 Python's representation base is binary. Other bases (including decimal!) use |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2062 the simple quadratic-time algorithm below, complicated by some speed tricks. |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2063 |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2064 First some math: the largest integer that can be expressed in N base-B digits |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2065 is B**N-1. Consequently, if we have an N-digit input in base B, the worst- |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2066 case number of Python digits needed to hold it is the smallest integer n s.t. |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2067 |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2068 BASE**n-1 >= B**N-1 [or, adding 1 to both sides] |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2069 BASE**n >= B**N [taking logs to base BASE] |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2070 n >= log(B**N)/log(BASE) = N * log(B)/log(BASE) |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2071 |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2072 The static array log_base_BASE[base] == log(base)/log(BASE) so we can compute |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
2073 this quickly. A Python int with that much space is reserved near the start, |
|
38453
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2074 and the result is computed into it. |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2075 |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2076 The input string is actually treated as being in base base**i (i.e., i digits |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2077 are processed at a time), where two more static arrays hold: |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2078 |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2079 convwidth_base[base] = the largest integer i such that base**i <= BASE |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2080 convmultmax_base[base] = base ** convwidth_base[base] |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2081 |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2082 The first of these is the largest i such that i consecutive input digits |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2083 must fit in a single Python digit. The second is effectively the input |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2084 base we're really using. |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2085 |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2086 Viewing the input as a sequence <c0, c1, ..., c_n-1> of digits in base |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2087 convmultmax_base[base], the result is "simply" |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2088 |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2089 (((c0*B + c1)*B + c2)*B + c3)*B + ... ))) + c_n-1 |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2090 |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2091 where B = convmultmax_base[base]. |
|
38669
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2092 |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2093 Error analysis: as above, the number of Python digits `n` needed is worst- |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2094 case |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2095 |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2096 n >= N * log(B)/log(BASE) |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2097 |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2098 where `N` is the number of input digits in base `B`. This is computed via |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2099 |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2100 size_z = (Py_ssize_t)((scan - str) * log_base_BASE[base]) + 1; |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2101 |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2102 below. Two numeric concerns are how much space this can waste, and whether |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2103 the computed result can be too small. To be concrete, assume BASE = 2**15, |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2104 which is the default (and it's unlikely anyone changes that). |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2105 |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2106 Waste isn't a problem: provided the first input digit isn't 0, the difference |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2107 between the worst-case input with N digits and the smallest input with N |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2108 digits is about a factor of B, but B is small compared to BASE so at most |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2109 one allocated Python digit can remain unused on that count. If |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2110 N*log(B)/log(BASE) is mathematically an exact integer, then truncating that |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2111 and adding 1 returns a result 1 larger than necessary. However, that can't |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2112 happen: whenever B is a power of 2, long_from_binary_base() is called |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2113 instead, and it's impossible for B**i to be an integer power of 2**15 when |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2114 B is not a power of 2 (i.e., it's impossible for N*log(B)/log(BASE) to be |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2115 an exact integer when B is not a power of 2, since B**i has a prime factor |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2116 other than 2 in that case, but (2**15)**j's only prime factor is 2). |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2117 |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2118 The computed result can be too small if the true value of N*log(B)/log(BASE) |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2119 is a little bit larger than an exact integer, but due to roundoff errors (in |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2120 computing log(B), log(BASE), their quotient, and/or multiplying that by N) |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2121 yields a numeric result a little less than that integer. Unfortunately, "how |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2122 close can a transcendental function get to an integer over some range?" |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2123 questions are generally theoretically intractable. Computer analysis via |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2124 continued fractions is practical: expand log(B)/log(BASE) via continued |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2125 fractions, giving a sequence i/j of "the best" rational approximations. Then |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2126 j*log(B)/log(BASE) is approximately equal to (the integer) i. This shows that |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2127 we can get very close to being in trouble, but very rarely. For example, |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2128 76573 is a denominator in one of the continued-fraction approximations to |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2129 log(10)/log(2**15), and indeed: |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2130 |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2131 >>> log(10)/log(2**15)*76573 |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2132 16958.000000654003 |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2133 |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2134 is very close to an integer. If we were working with IEEE single-precision, |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2135 rounding errors could kill us. Finding worst cases in IEEE double-precision |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2136 requires better-than-double-precision log() functions, and Tim didn't bother. |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2137 Instead the code checks to see whether the allocated space is enough as each |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
2138 new Python digit is added, and copies the whole thing to a larger int if not. |
|
38669
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2139 This should happen extremely rarely, and in fact I don't have a test case |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2140 that triggers it(!). Instead the code was tested by artificially allocating |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2141 just 1 digit at the start, so that the copying code was exercised for every |
|
19fd6141940d
Partially merge trunk into p3yk. The removal of Mac/Tools is confusing svn
Thomas Wouters <thomas@python.org>
parents:
38453
diff
changeset
|
2142 digit beyond the first. |
|
38453
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
37879
diff
changeset
|
2143 ***/ |
|
85157
e7f6cef7a4cc
Issue #18722: Remove uses of the "register" keyword in C code.
Antoine Pitrou <solipsis@pitrou.net>
parents:
84996
diff
changeset
|
2144 twodigits c; /* current input character */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2145 Py_ssize_t size_z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2146 int i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2147 int convwidth; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2148 twodigits convmultmax, convmult; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2149 digit *pz, *pzstop; |
|
86484
3055e61f1e66
Issue #1772673: The type of `char*` arguments now changed to `const char*`.
Serhiy Storchaka <storchaka@gmail.com>
parents:
85982
diff
changeset
|
2150 const char* scan; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2151 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2152 static double log_base_BASE[37] = {0.0e0,}; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2153 static int convwidth_base[37] = {0,}; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2154 static twodigits convmultmax_base[37] = {0,}; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2155 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2156 if (log_base_BASE[base] == 0.0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2157 twodigits convmax = base; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2158 int i = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2159 |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2160 log_base_BASE[base] = (log((double)base) / |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2161 log((double)PyLong_BASE)); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2162 for (;;) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2163 twodigits next = convmax * base; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2164 if (next > PyLong_BASE) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2165 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2166 convmax = next; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2167 ++i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2168 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2169 convmultmax_base[base] = convmax; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2170 assert(i > 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2171 convwidth_base[base] = i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2172 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2173 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2174 /* Find length of the string of numeric characters. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2175 scan = str; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2176 while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2177 ++scan; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2178 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
2179 /* Create an int object that can contain the largest possible |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2180 * integer with this base and length. Note that there's no |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2181 * need to initialize z->ob_digit -- no slot is read up before |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2182 * being stored into. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2183 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2184 size_z = (Py_ssize_t)((scan - str) * log_base_BASE[base]) + 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2185 /* Uncomment next line to test exceedingly rare copy code */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2186 /* size_z = 1; */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2187 assert(size_z > 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2188 z = _PyLong_New(size_z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2189 if (z == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2190 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2191 Py_SIZE(z) = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2192 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2193 /* `convwidth` consecutive input digits are treated as a single |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2194 * digit in base `convmultmax`. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2195 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2196 convwidth = convwidth_base[base]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2197 convmultmax = convmultmax_base[base]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2198 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2199 /* Work ;-) */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2200 while (str < scan) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2201 /* grab up to convwidth digits from the input string */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2202 c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2203 for (i = 1; i < convwidth && str != scan; ++i, ++str) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2204 c = (twodigits)(c * base + |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2205 (int)_PyLong_DigitValue[Py_CHARMASK(*str)]); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2206 assert(c < PyLong_BASE); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2207 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2208 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2209 convmult = convmultmax; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2210 /* Calculate the shift only if we couldn't get |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2211 * convwidth digits. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2212 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2213 if (i != convwidth) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2214 convmult = base; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2215 for ( ; i > 1; --i) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2216 convmult *= base; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2217 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2218 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2219 /* Multiply z by convmult, and add c. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2220 pz = z->ob_digit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2221 pzstop = pz + Py_SIZE(z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2222 for (; pz < pzstop; ++pz) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2223 c += (twodigits)*pz * convmult; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2224 *pz = (digit)(c & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2225 c >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2226 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2227 /* carry off the current end? */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2228 if (c) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2229 assert(c < PyLong_BASE); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2230 if (Py_SIZE(z) < size_z) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2231 *pz = (digit)c; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2232 ++Py_SIZE(z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2233 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2234 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2235 PyLongObject *tmp; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2236 /* Extremely rare. Get more space. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2237 assert(Py_SIZE(z) == size_z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2238 tmp = _PyLong_New(size_z + 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2239 if (tmp == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2240 Py_DECREF(z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2241 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2242 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2243 memcpy(tmp->ob_digit, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2244 z->ob_digit, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2245 sizeof(digit) * size_z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2246 Py_DECREF(z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2247 z = tmp; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2248 z->ob_digit[size_z] = (digit)c; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2249 ++size_z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2250 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2251 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2252 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2253 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2254 if (z == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2255 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2256 if (error_if_nonzero) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2257 /* reset the base to 0, else the exception message |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2258 doesn't make too much sense */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2259 base = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2260 if (Py_SIZE(z) != 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2261 goto onError; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2262 /* there might still be other problems, therefore base |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2263 remains zero here for the same reason */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2264 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2265 if (str == start) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2266 goto onError; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2267 if (sign < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2268 Py_SIZE(z) = -(Py_SIZE(z)); |
|
82110
38830281d43b
Issue #17173: Remove uses of locale-dependent C functions (isalpha() etc.) in the interpreter.
Antoine Pitrou <solipsis@pitrou.net>
parents:
81587
diff
changeset
|
2269 while (*str && Py_ISSPACE(Py_CHARMASK(*str))) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2270 str++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2271 if (*str != '\0') |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2272 goto onError; |
|
84995
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2273 long_normalize(z); |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2274 z = maybe_small_long(z); |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2275 if (z == NULL) |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2276 return NULL; |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2277 if (pend != NULL) |
|
86484
3055e61f1e66
Issue #1772673: The type of `char*` arguments now changed to `const char*`.
Serhiy Storchaka <storchaka@gmail.com>
parents:
85982
diff
changeset
|
2278 *pend = (char *)str; |
|
84995
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2279 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
|
2280 |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2281 onError: |
|
84995
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2282 if (pend != NULL) |
|
86484
3055e61f1e66
Issue #1772673: The type of `char*` arguments now changed to `const char*`.
Serhiy Storchaka <storchaka@gmail.com>
parents:
85982
diff
changeset
|
2283 *pend = (char *)str; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2284 Py_XDECREF(z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2285 slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2286 strobj = PyUnicode_FromStringAndSize(orig_str, slen); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2287 if (strobj == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2288 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2289 PyErr_Format(PyExc_ValueError, |
|
84996
4fd48a807812
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
diff
changeset
|
2290 "invalid literal for int() with base %d: %.200R", |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2291 base, strobj); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2292 Py_DECREF(strobj); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2293 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
|
2294 } |
|
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
|
2295 |
|
84995
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2296 /* Since PyLong_FromString doesn't have a length parameter, |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2297 * check here for possible NULs in the string. |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2298 * |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2299 * Reports an invalid literal as a bytes object. |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2300 */ |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2301 PyObject * |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2302 _PyLong_FromBytes(const char *s, Py_ssize_t len, int base) |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2303 { |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2304 PyObject *result, *strobj; |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2305 char *end = NULL; |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2306 |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2307 result = PyLong_FromString((char*)s, &end, base); |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2308 if (end == NULL || (result != NULL && end == s + len)) |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2309 return result; |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2310 Py_XDECREF(result); |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2311 strobj = PyBytes_FromStringAndSize(s, Py_MIN(len, 200)); |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2312 if (strobj != NULL) { |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2313 PyErr_Format(PyExc_ValueError, |
|
84996
4fd48a807812
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
diff
changeset
|
2314 "invalid literal for int() with base %d: %.200R", |
|
84995
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2315 base, strobj); |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2316 Py_DECREF(strobj); |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2317 } |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2318 return NULL; |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2319 } |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2320 |
|
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
|
2321 PyObject * |
|
36501
7fdc639bc5b4
Merge ssize_t branch.
Martin v. Löwis <martin@v.loewis.de>
parents:
36430
diff
changeset
|
2322 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
|
2323 { |
| 72475 | 2324 PyObject *v, *unicode = PyUnicode_FromUnicode(u, length); |
| 2325 if (unicode == NULL) | |
| 2326 return NULL; | |
| 2327 v = PyLong_FromUnicodeObject(unicode, base); | |
| 2328 Py_DECREF(unicode); | |
| 2329 return v; | |
| 2330 } | |
| 2331 | |
| 2332 PyObject * | |
| 2333 PyLong_FromUnicodeObject(PyObject *u, int base) | |
| 2334 { | |
|
84996
4fd48a807812
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
diff
changeset
|
2335 PyObject *result, *asciidig; |
|
84995
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2336 char *buffer, *end = NULL; |
| 72475 | 2337 Py_ssize_t buflen; |
| 2338 | |
| 2339 asciidig = _PyUnicode_TransformDecimalAndSpaceToASCII(u); | |
|
66673
7b6af56ee74d
Issue #10557: Fixed error messages from float() and other numeric
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
66555
diff
changeset
|
2340 if (asciidig == NULL) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2341 return NULL; |
| 72475 | 2342 buffer = PyUnicode_AsUTF8AndSize(asciidig, &buflen); |
|
66673
7b6af56ee74d
Issue #10557: Fixed error messages from float() and other numeric
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
66555
diff
changeset
|
2343 if (buffer == NULL) { |
|
7b6af56ee74d
Issue #10557: Fixed error messages from float() and other numeric
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
66555
diff
changeset
|
2344 Py_DECREF(asciidig); |
|
84995
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2345 if (!PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2346 return NULL; |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2347 } |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2348 else { |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2349 result = PyLong_FromString(buffer, &end, base); |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2350 if (end == NULL || (result != NULL && end == buffer + buflen)) { |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2351 Py_DECREF(asciidig); |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2352 return result; |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2353 } |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2354 Py_DECREF(asciidig); |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2355 Py_XDECREF(result); |
|
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2356 } |
|
84996
4fd48a807812
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
diff
changeset
|
2357 PyErr_Format(PyExc_ValueError, |
|
4fd48a807812
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
diff
changeset
|
2358 "invalid literal for int() with base %d: %.200R", |
|
4fd48a807812
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
diff
changeset
|
2359 base, u); |
|
84995
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
2360 return NULL; |
| 230 | 2361 } |
| 2362 | |
|
13406
a503af7e7fb7
Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents:
13256
diff
changeset
|
2363 /* forward */ |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
2364 static PyLongObject *x_divrem |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2365 (PyLongObject *, PyLongObject *, PyLongObject **); |
|
42417
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
2366 static PyObject *long_long(PyObject *v); |
| 230 | 2367 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
2368 /* Int division with remainder, top-level routine */ |
| 230 | 2369 |
| 613 | 2370 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
|
2371 long_divrem(PyLongObject *a, PyLongObject *b, |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2372 PyLongObject **pdiv, PyLongObject **prem) |
| 230 | 2373 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2374 Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2375 PyLongObject *z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2376 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2377 if (size_b == 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2378 PyErr_SetString(PyExc_ZeroDivisionError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2379 "integer division or modulo by zero"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2380 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2381 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2382 if (size_a < size_b || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2383 (size_a == size_b && |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2384 a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2385 /* |a| < |b|. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2386 *pdiv = (PyLongObject*)PyLong_FromLong(0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2387 if (*pdiv == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2388 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2389 Py_INCREF(a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2390 *prem = (PyLongObject *) a; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2391 return 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2392 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2393 if (size_b == 1) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2394 digit rem = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2395 z = divrem1(a, b->ob_digit[0], &rem); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2396 if (z == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2397 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2398 *prem = (PyLongObject *) PyLong_FromLong((long)rem); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2399 if (*prem == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2400 Py_DECREF(z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2401 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2402 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2403 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2404 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2405 z = x_divrem(a, b, prem); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2406 if (z == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2407 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2408 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2409 /* Set the signs. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2410 The quotient z has the sign of a*b; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2411 the remainder r has the sign of a, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2412 so a = b*z + r. */ |
|
84698
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2413 if ((Py_SIZE(a) < 0) != (Py_SIZE(b) < 0)) { |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2414 _PyLong_Negate(&z); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2415 if (z == NULL) { |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2416 Py_CLEAR(*prem); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2417 return -1; |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2418 } |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2419 } |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2420 if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) { |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2421 _PyLong_Negate(prem); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2422 if (*prem == NULL) { |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2423 Py_DECREF(z); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2424 Py_CLEAR(*prem); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2425 return -1; |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2426 } |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2427 } |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2428 *pdiv = maybe_small_long(z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2429 return 0; |
| 230 | 2430 } |
| 2431 | |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
2432 /* Unsigned int division with remainder -- the algorithm. The arguments v1 |
|
52289
a1d16d98aa40
Merged revisions 70542 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
52215
diff
changeset
|
2433 and w1 should satisfy 2 <= ABS(Py_SIZE(w1)) <= ABS(Py_SIZE(v1)). */ |
| 230 | 2434 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
2435 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
|
2436 x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) |
| 230 | 2437 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2438 PyLongObject *v, *w, *a; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2439 Py_ssize_t i, k, size_v, size_w; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2440 int d; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2441 digit wm1, wm2, carry, q, r, vtop, *v0, *vk, *w0, *ak; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2442 twodigits vv; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2443 sdigit zhi; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2444 stwodigits z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2445 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2446 /* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2447 edn.), section 4.3.1, Algorithm D], except that we don't explicitly |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2448 handle the special case when the initial estimate q for a quotient |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2449 digit is >= PyLong_BASE: the max value for q is PyLong_BASE+1, and |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2450 that won't overflow a digit. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2451 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2452 /* allocate space; w will also be used to hold the final remainder */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2453 size_v = ABS(Py_SIZE(v1)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2454 size_w = ABS(Py_SIZE(w1)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2455 assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2456 v = _PyLong_New(size_v+1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2457 if (v == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2458 *prem = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2459 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2460 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2461 w = _PyLong_New(size_w); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2462 if (w == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2463 Py_DECREF(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2464 *prem = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2465 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2466 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2467 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2468 /* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2469 shift v1 left by the same amount. Results go into w and v. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2470 d = PyLong_SHIFT - bits_in_digit(w1->ob_digit[size_w-1]); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2471 carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2472 assert(carry == 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2473 carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2474 if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2475 v->ob_digit[size_v] = carry; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2476 size_v++; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2477 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2478 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2479 /* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2480 at most (and usually exactly) k = size_v - size_w digits. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2481 k = size_v - size_w; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2482 assert(k >= 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2483 a = _PyLong_New(k); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2484 if (a == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2485 Py_DECREF(w); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2486 Py_DECREF(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2487 *prem = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2488 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2489 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2490 v0 = v->ob_digit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2491 w0 = w->ob_digit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2492 wm1 = w0[size_w-1]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2493 wm2 = w0[size_w-2]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2494 for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2495 /* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2496 single-digit quotient q, remainder in vk[0:size_w]. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2497 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2498 SIGCHECK({ |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2499 Py_DECREF(a); |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2500 Py_DECREF(w); |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2501 Py_DECREF(v); |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2502 *prem = NULL; |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2503 return NULL; |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
2504 }); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2505 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2506 /* estimate quotient digit q; may overestimate by 1 (rare) */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2507 vtop = vk[size_w]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2508 assert(vtop <= wm1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2509 vv = ((twodigits)vtop << PyLong_SHIFT) | vk[size_w-1]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2510 q = (digit)(vv / wm1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2511 r = (digit)(vv - (twodigits)wm1 * q); /* r = vv % wm1 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2512 while ((twodigits)wm2 * q > (((twodigits)r << PyLong_SHIFT) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2513 | vk[size_w-2])) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2514 --q; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2515 r += wm1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2516 if (r >= PyLong_BASE) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2517 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2518 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2519 assert(q <= PyLong_BASE); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2520 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2521 /* subtract q*w0[0:size_w] from vk[0:size_w+1] */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2522 zhi = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2523 for (i = 0; i < size_w; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2524 /* invariants: -PyLong_BASE <= -q <= zhi <= 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2525 -PyLong_BASE * q <= z < PyLong_BASE */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2526 z = (sdigit)vk[i] + zhi - |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2527 (stwodigits)q * (stwodigits)w0[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2528 vk[i] = (digit)z & PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2529 zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits, |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2530 z, PyLong_SHIFT); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2531 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2532 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2533 /* add w back if q was too large (this branch taken rarely) */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2534 assert((sdigit)vtop + zhi == -1 || (sdigit)vtop + zhi == 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2535 if ((sdigit)vtop + zhi < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2536 carry = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2537 for (i = 0; i < size_w; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2538 carry += vk[i] + w0[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2539 vk[i] = carry & PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2540 carry >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2541 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2542 --q; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2543 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2544 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2545 /* store quotient digit */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2546 assert(q < PyLong_BASE); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2547 *--ak = q; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2548 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2549 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2550 /* unshift remainder; we reuse w to store the result */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2551 carry = v_rshift(w0, v0, size_w, d); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2552 assert(carry==0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2553 Py_DECREF(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2554 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2555 *prem = long_normalize(w); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2556 return long_normalize(a); |
| 230 | 2557 } |
| 2558 | |
|
58088
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2559 /* For a nonzero PyLong a, express a in the form x * 2**e, with 0.5 <= |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2560 abs(x) < 1.0 and e >= 0; return x and put e in *e. Here x is |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2561 rounded to DBL_MANT_DIG significant bits using round-half-to-even. |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2562 If a == 0, return 0.0 and set *e = 0. If the resulting exponent |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2563 e is larger than PY_SSIZE_T_MAX, raise OverflowError and return |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2564 -1.0. */ |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2565 |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2566 /* attempt to define 2.0**DBL_MANT_DIG as a compile-time constant */ |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2567 #if DBL_MANT_DIG == 53 |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2568 #define EXP2_DBL_MANT_DIG 9007199254740992.0 |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2569 #else |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2570 #define EXP2_DBL_MANT_DIG (ldexp(1.0, DBL_MANT_DIG)) |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2571 #endif |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2572 |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2573 double |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2574 _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2575 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2576 Py_ssize_t a_size, a_bits, shift_digits, shift_bits, x_size; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2577 /* See below for why x_digits is always large enough. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2578 digit rem, x_digits[2 + (DBL_MANT_DIG + 1) / PyLong_SHIFT]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2579 double dx; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2580 /* Correction term for round-half-to-even rounding. For a digit x, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2581 "x + half_even_correction[x & 7]" gives x rounded to the nearest |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2582 multiple of 4, rounding ties to a multiple of 8. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2583 static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1}; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2584 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2585 a_size = ABS(Py_SIZE(a)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2586 if (a_size == 0) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2587 /* Special case for 0: significand 0.0, exponent 0. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2588 *e = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2589 return 0.0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2590 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2591 a_bits = bits_in_digit(a->ob_digit[a_size-1]); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2592 /* The following is an overflow-free version of the check |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2593 "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2594 if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 && |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2595 (a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 || |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2596 a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1)) |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2597 goto overflow; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2598 a_bits = (a_size - 1) * PyLong_SHIFT + a_bits; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2599 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2600 /* Shift the first DBL_MANT_DIG + 2 bits of a into x_digits[0:x_size] |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2601 (shifting left if a_bits <= DBL_MANT_DIG + 2). |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2602 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2603 Number of digits needed for result: write // for floor division. |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2604 Then if shifting left, we end up using |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2605 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2606 1 + a_size + (DBL_MANT_DIG + 2 - a_bits) // PyLong_SHIFT |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2607 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2608 digits. If shifting right, we use |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2609 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2610 a_size - (a_bits - DBL_MANT_DIG - 2) // PyLong_SHIFT |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2611 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2612 digits. Using a_size = 1 + (a_bits - 1) // PyLong_SHIFT along with |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2613 the inequalities |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2614 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2615 m // PyLong_SHIFT + n // PyLong_SHIFT <= (m + n) // PyLong_SHIFT |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2616 m // PyLong_SHIFT - n // PyLong_SHIFT <= |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2617 1 + (m - n - 1) // PyLong_SHIFT, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2618 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2619 valid for any integers m and n, we find that x_size satisfies |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2620 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2621 x_size <= 2 + (DBL_MANT_DIG + 1) // PyLong_SHIFT |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2622 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2623 in both cases. |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2624 */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2625 if (a_bits <= DBL_MANT_DIG + 2) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2626 shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2627 shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2628 x_size = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2629 while (x_size < shift_digits) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2630 x_digits[x_size++] = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2631 rem = v_lshift(x_digits + x_size, a->ob_digit, a_size, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2632 (int)shift_bits); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2633 x_size += a_size; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2634 x_digits[x_size++] = rem; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2635 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2636 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2637 shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2638 shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2639 rem = v_rshift(x_digits, a->ob_digit + shift_digits, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2640 a_size - shift_digits, (int)shift_bits); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2641 x_size = a_size - shift_digits; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2642 /* For correct rounding below, we need the least significant |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2643 bit of x to be 'sticky' for this shift: if any of the bits |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2644 shifted out was nonzero, we set the least significant bit |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2645 of x. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2646 if (rem) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2647 x_digits[0] |= 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2648 else |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2649 while (shift_digits > 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2650 if (a->ob_digit[--shift_digits]) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2651 x_digits[0] |= 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2652 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2653 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2654 } |
|
72510
b534b56379cb
Use the new Py_ARRAY_LENGTH macro
Victor Stinner <victor.stinner@haypocalc.com>
parents:
72475
diff
changeset
|
2655 assert(1 <= x_size && x_size <= (Py_ssize_t)Py_ARRAY_LENGTH(x_digits)); |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2656 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2657 /* Round, and convert to double. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2658 x_digits[0] += half_even_correction[x_digits[0] & 7]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2659 dx = x_digits[--x_size]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2660 while (x_size > 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2661 dx = dx * PyLong_BASE + x_digits[--x_size]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2662 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2663 /* Rescale; make correction if result is 1.0. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2664 dx /= 4.0 * EXP2_DBL_MANT_DIG; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2665 if (dx == 1.0) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2666 if (a_bits == PY_SSIZE_T_MAX) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2667 goto overflow; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2668 dx = 0.5; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2669 a_bits += 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2670 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2671 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2672 *e = a_bits; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2673 return Py_SIZE(a) < 0 ? -dx : dx; |
|
58088
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2674 |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2675 overflow: |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2676 /* exponent > PY_SSIZE_T_MAX */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2677 PyErr_SetString(PyExc_OverflowError, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2678 "huge integer: number of bits overflows a Py_ssize_t"); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2679 *e = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2680 return -1.0; |
|
58088
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2681 } |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2682 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
2683 /* Get a C double from an int object. Rounds to the nearest double, |
|
58088
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2684 using the round-half-to-even rule in the case of a tie. */ |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2685 |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2686 double |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2687 PyLong_AsDouble(PyObject *v) |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2688 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2689 Py_ssize_t exponent; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2690 double x; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2691 |
|
72312
4a66a35da3fd
Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.
Nadeem Vawda <nadeem.vawda@gmail.com>
parents:
71810
diff
changeset
|
2692 if (v == NULL) { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2693 PyErr_BadInternalCall(); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2694 return -1.0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2695 } |
|
72312
4a66a35da3fd
Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.
Nadeem Vawda <nadeem.vawda@gmail.com>
parents:
71810
diff
changeset
|
2696 if (!PyLong_Check(v)) { |
|
4a66a35da3fd
Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.
Nadeem Vawda <nadeem.vawda@gmail.com>
parents:
71810
diff
changeset
|
2697 PyErr_SetString(PyExc_TypeError, "an integer is required"); |
|
4a66a35da3fd
Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.
Nadeem Vawda <nadeem.vawda@gmail.com>
parents:
71810
diff
changeset
|
2698 return -1.0; |
|
4a66a35da3fd
Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.
Nadeem Vawda <nadeem.vawda@gmail.com>
parents:
71810
diff
changeset
|
2699 } |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2700 x = _PyLong_Frexp((PyLongObject *)v, &exponent); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2701 if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2702 PyErr_SetString(PyExc_OverflowError, |
|
84983
dab7d6f33b87
Minor consistency fixes for some longobject.c exception messages:
Mark Dickinson <dickinsm@gmail.com>
parents:
84793
diff
changeset
|
2703 "int too large to convert to float"); |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2704 return -1.0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2705 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2706 return ldexp(x, (int)exponent); |
|
58088
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2707 } |
|
46d60e5ff103
Merged revisions 77234 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57942
diff
changeset
|
2708 |
| 230 | 2709 /* Methods */ |
| 2710 | |
| 2711 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
|
2712 long_dealloc(PyObject *v) |
| 230 | 2713 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2714 Py_TYPE(v)->tp_free(v); |
| 230 | 2715 } |
| 2716 | |
| 2717 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
|
2718 long_compare(PyLongObject *a, PyLongObject *b) |
| 230 | 2719 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2720 Py_ssize_t sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2721 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2722 if (Py_SIZE(a) != Py_SIZE(b)) { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
2723 sign = Py_SIZE(a) - Py_SIZE(b); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2724 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2725 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2726 Py_ssize_t i = ABS(Py_SIZE(a)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2727 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2728 ; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2729 if (i < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2730 sign = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2731 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2732 sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2733 if (Py_SIZE(a) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2734 sign = -sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2735 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2736 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2737 return sign < 0 ? -1 : sign > 0 ? 1 : 0; |
| 230 | 2738 } |
| 2739 | |
|
50241
45bea584694e
Issue #3106: Speedup some comparisons. This also removes the last call
Antoine Pitrou <solipsis@pitrou.net>
parents:
50207
diff
changeset
|
2740 #define TEST_COND(cond) \ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2741 ((cond) ? Py_True : Py_False) |
|
50241
45bea584694e
Issue #3106: Speedup some comparisons. This also removes the last call
Antoine Pitrou <solipsis@pitrou.net>
parents:
50207
diff
changeset
|
2742 |
|
39644
13d5e5f0e993
Restructure comparison dramatically. There is no longer a default
Guido van Rossum <guido@python.org>
parents:
39610
diff
changeset
|
2743 static PyObject * |
|
13d5e5f0e993
Restructure comparison dramatically. There is no longer a default
Guido van Rossum <guido@python.org>
parents:
39610
diff
changeset
|
2744 long_richcompare(PyObject *self, PyObject *other, int op) |
|
13d5e5f0e993
Restructure comparison dramatically. There is no longer a default
Guido van Rossum <guido@python.org>
parents:
39610
diff
changeset
|
2745 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2746 int result; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2747 PyObject *v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2748 CHECK_BINOP(self, other); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2749 if (self == other) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2750 result = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2751 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2752 result = long_compare((PyLongObject*)self, (PyLongObject*)other); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2753 /* Convert the return value to a Boolean */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2754 switch (op) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2755 case Py_EQ: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2756 v = TEST_COND(result == 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2757 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2758 case Py_NE: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2759 v = TEST_COND(result != 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2760 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2761 case Py_LE: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2762 v = TEST_COND(result <= 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2763 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2764 case Py_GE: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2765 v = TEST_COND(result >= 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2766 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2767 case Py_LT: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2768 v = TEST_COND(result == -1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2769 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2770 case Py_GT: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2771 v = TEST_COND(result == 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2772 break; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2773 default: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2774 PyErr_BadArgument(); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2775 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2776 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2777 Py_INCREF(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2778 return v; |
|
39644
13d5e5f0e993
Restructure comparison dramatically. There is no longer a default
Guido van Rossum <guido@python.org>
parents:
39610
diff
changeset
|
2779 } |
|
13d5e5f0e993
Restructure comparison dramatically. There is no longer a default
Guido van Rossum <guido@python.org>
parents:
39610
diff
changeset
|
2780 |
|
65494
e8969fb822fc
make hashes always the size of pointers; introduce Py_hash_t #9778
Benjamin Peterson <benjamin@python.org>
parents:
62154
diff
changeset
|
2781 static Py_hash_t |
|
13406
a503af7e7fb7
Some cleanup of longs in prepartion for Cray J90 fixes: got
Tim Peters <tim.peters@gmail.com>
parents:
13256
diff
changeset
|
2782 long_hash(PyLongObject *v) |
|
1257
1cabc2b6c970
* Changed all copyright messages to include 1993.
Guido van Rossum <guido@python.org>
parents:
1252
diff
changeset
|
2783 { |
|
65603
be8ae6b17539
follow up to #9778: define and use an unsigned hash type
Benjamin Peterson <benjamin@python.org>
parents:
65494
diff
changeset
|
2784 Py_uhash_t x; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2785 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2786 int sign; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2787 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2788 i = Py_SIZE(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2789 switch(i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2790 case -1: return v->ob_digit[0]==1 ? -2 : -(sdigit)v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2791 case 0: return 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2792 case 1: return v->ob_digit[0]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2793 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2794 sign = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2795 x = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2796 if (i < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2797 sign = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2798 i = -(i); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2799 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2800 while (--i >= 0) { |
|
61873
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2801 /* Here x is a quantity in the range [0, _PyHASH_MODULUS); we |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2802 want to compute x * 2**PyLong_SHIFT + v->ob_digit[i] modulo |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2803 _PyHASH_MODULUS. |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2804 |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2805 The computation of x * 2**PyLong_SHIFT % _PyHASH_MODULUS |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2806 amounts to a rotation of the bits of x. To see this, write |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2807 |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2808 x * 2**PyLong_SHIFT = y * 2**_PyHASH_BITS + z |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2809 |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2810 where y = x >> (_PyHASH_BITS - PyLong_SHIFT) gives the top |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2811 PyLong_SHIFT bits of x (those that are shifted out of the |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2812 original _PyHASH_BITS bits, and z = (x << PyLong_SHIFT) & |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2813 _PyHASH_MODULUS gives the bottom _PyHASH_BITS - PyLong_SHIFT |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2814 bits of x, shifted up. Then since 2**_PyHASH_BITS is |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2815 congruent to 1 modulo _PyHASH_MODULUS, y*2**_PyHASH_BITS is |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2816 congruent to y modulo _PyHASH_MODULUS. So |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2817 |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2818 x * 2**PyLong_SHIFT = y + z (mod _PyHASH_MODULUS). |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2819 |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2820 The right-hand side is just the result of rotating the |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2821 _PyHASH_BITS bits of x left by PyLong_SHIFT places; since |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2822 not all _PyHASH_BITS bits of x are 1s, the same is true |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2823 after rotation, so 0 <= y+z < _PyHASH_MODULUS and y + z is |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2824 the reduction of x*2**PyLong_SHIFT modulo |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2825 _PyHASH_MODULUS. */ |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2826 x = ((x << PyLong_SHIFT) & _PyHASH_MODULUS) | |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2827 (x >> (_PyHASH_BITS - PyLong_SHIFT)); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2828 x += v->ob_digit[i]; |
|
61873
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2829 if (x >= _PyHASH_MODULUS) |
|
0bc8ffe6ba9a
Issue #8188: Introduce a new scheme for computing hashes of numbers
Mark Dickinson <dickinsm@gmail.com>
parents:
61492
diff
changeset
|
2830 x -= _PyHASH_MODULUS; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2831 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2832 x = x * sign; |
|
65603
be8ae6b17539
follow up to #9778: define and use an unsigned hash type
Benjamin Peterson <benjamin@python.org>
parents:
65494
diff
changeset
|
2833 if (x == (Py_uhash_t)-1) |
|
be8ae6b17539
follow up to #9778: define and use an unsigned hash type
Benjamin Peterson <benjamin@python.org>
parents:
65494
diff
changeset
|
2834 x = (Py_uhash_t)-2; |
|
65494
e8969fb822fc
make hashes always the size of pointers; introduce Py_hash_t #9778
Benjamin Peterson <benjamin@python.org>
parents:
62154
diff
changeset
|
2835 return (Py_hash_t)x; |
|
1257
1cabc2b6c970
* Changed all copyright messages to include 1993.
Guido van Rossum <guido@python.org>
parents:
1252
diff
changeset
|
2836 } |
|
1cabc2b6c970
* Changed all copyright messages to include 1993.
Guido van Rossum <guido@python.org>
parents:
1252
diff
changeset
|
2837 |
|
1cabc2b6c970
* Changed all copyright messages to include 1993.
Guido van Rossum <guido@python.org>
parents:
1252
diff
changeset
|
2838 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
2839 /* Add the absolute values of two integers. */ |
| 230 | 2840 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
2841 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
|
2842 x_add(PyLongObject *a, PyLongObject *b) |
| 230 | 2843 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2844 Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2845 PyLongObject *z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2846 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2847 digit carry = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2848 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2849 /* Ensure a is the larger of the two: */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2850 if (size_a < size_b) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2851 { PyLongObject *temp = a; a = b; b = temp; } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2852 { Py_ssize_t size_temp = size_a; |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2853 size_a = size_b; |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2854 size_b = size_temp; } |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2855 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2856 z = _PyLong_New(size_a+1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2857 if (z == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2858 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2859 for (i = 0; i < size_b; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2860 carry += a->ob_digit[i] + b->ob_digit[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2861 z->ob_digit[i] = carry & PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2862 carry >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2863 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2864 for (; i < size_a; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2865 carry += a->ob_digit[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2866 z->ob_digit[i] = carry & PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2867 carry >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2868 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2869 z->ob_digit[i] = carry; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2870 return long_normalize(z); |
| 230 | 2871 } |
| 2872 | |
| 2873 /* Subtract the absolute values of two integers. */ | |
| 2874 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
2875 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
|
2876 x_sub(PyLongObject *a, PyLongObject *b) |
| 230 | 2877 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2878 Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2879 PyLongObject *z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2880 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2881 int sign = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2882 digit borrow = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2883 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2884 /* Ensure a is the larger of the two: */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2885 if (size_a < size_b) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2886 sign = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2887 { PyLongObject *temp = a; a = b; b = temp; } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2888 { Py_ssize_t size_temp = size_a; |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2889 size_a = size_b; |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
2890 size_b = size_temp; } |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2891 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2892 else if (size_a == size_b) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2893 /* Find highest digit where a and b differ: */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2894 i = size_a; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2895 while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2896 ; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2897 if (i < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2898 return (PyLongObject *)PyLong_FromLong(0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2899 if (a->ob_digit[i] < b->ob_digit[i]) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2900 sign = -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2901 { PyLongObject *temp = a; a = b; b = temp; } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2902 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2903 size_a = size_b = i+1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2904 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2905 z = _PyLong_New(size_a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2906 if (z == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2907 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2908 for (i = 0; i < size_b; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2909 /* The following assumes unsigned arithmetic |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2910 works module 2**N for some N>PyLong_SHIFT. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2911 borrow = a->ob_digit[i] - b->ob_digit[i] - borrow; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2912 z->ob_digit[i] = borrow & PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2913 borrow >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2914 borrow &= 1; /* Keep only one sign bit */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2915 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2916 for (; i < size_a; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2917 borrow = a->ob_digit[i] - borrow; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2918 z->ob_digit[i] = borrow & PyLong_MASK; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2919 borrow >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2920 borrow &= 1; /* Keep only one sign bit */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2921 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2922 assert(borrow == 0); |
|
84698
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2923 if (sign < 0) { |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2924 _PyLong_Negate(&z); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2925 if (z == NULL) |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2926 return NULL; |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
2927 } |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2928 return long_normalize(z); |
| 230 | 2929 } |
| 2930 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
2931 static PyObject * |
| 43313 | 2932 long_add(PyLongObject *a, PyLongObject *b) |
| 230 | 2933 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2934 PyLongObject *z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2935 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2936 CHECK_BINOP(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2937 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2938 if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2939 PyObject *result = PyLong_FromLong(MEDIUM_VALUE(a) + |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2940 MEDIUM_VALUE(b)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2941 return result; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2942 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2943 if (Py_SIZE(a) < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2944 if (Py_SIZE(b) < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2945 z = x_add(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2946 if (z != NULL && Py_SIZE(z) != 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2947 Py_SIZE(z) = -(Py_SIZE(z)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2948 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2949 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2950 z = x_sub(b, a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2951 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2952 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2953 if (Py_SIZE(b) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2954 z = x_sub(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2955 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2956 z = x_add(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2957 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2958 return (PyObject *)z; |
| 230 | 2959 } |
| 2960 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
2961 static PyObject * |
| 43313 | 2962 long_sub(PyLongObject *a, PyLongObject *b) |
| 230 | 2963 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2964 PyLongObject *z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2965 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2966 CHECK_BINOP(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2967 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2968 if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2969 PyObject* r; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2970 r = PyLong_FromLong(MEDIUM_VALUE(a)-MEDIUM_VALUE(b)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2971 return r; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2972 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2973 if (Py_SIZE(a) < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2974 if (Py_SIZE(b) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2975 z = x_sub(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2976 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2977 z = x_add(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2978 if (z != NULL && Py_SIZE(z) != 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2979 Py_SIZE(z) = -(Py_SIZE(z)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2980 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2981 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2982 if (Py_SIZE(b) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2983 z = x_add(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2984 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2985 z = x_sub(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2986 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2987 return (PyObject *)z; |
| 230 | 2988 } |
| 2989 | |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
2990 /* 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
|
2991 * 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
|
2992 */ |
|
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
2993 static PyLongObject * |
|
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
2994 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
|
2995 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2996 PyLongObject *z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2997 Py_ssize_t size_a = ABS(Py_SIZE(a)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2998 Py_ssize_t size_b = ABS(Py_SIZE(b)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
2999 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3000 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3001 z = _PyLong_New(size_a + size_b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3002 if (z == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3003 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3004 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3005 memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3006 if (a == b) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3007 /* Efficient squaring per HAC, Algorithm 14.16: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3008 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3009 * Gives slightly less than a 2x speedup when a == b, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3010 * via exploiting that each entry in the multiplication |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3011 * pyramid appears twice (except for the size_a squares). |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3012 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3013 for (i = 0; i < size_a; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3014 twodigits carry; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3015 twodigits f = a->ob_digit[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3016 digit *pz = z->ob_digit + (i << 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3017 digit *pa = a->ob_digit + i + 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3018 digit *paend = a->ob_digit + size_a; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3019 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3020 SIGCHECK({ |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3021 Py_DECREF(z); |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3022 return NULL; |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3023 }); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3024 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3025 carry = *pz + f * f; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3026 *pz++ = (digit)(carry & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3027 carry >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3028 assert(carry <= PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3029 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3030 /* Now f is added in twice in each column of the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3031 * pyramid it appears. Same as adding f<<1 once. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3032 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3033 f <<= 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3034 while (pa < paend) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3035 carry += *pz + *pa++ * f; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3036 *pz++ = (digit)(carry & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3037 carry >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3038 assert(carry <= (PyLong_MASK << 1)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3039 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3040 if (carry) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3041 carry += *pz; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3042 *pz++ = (digit)(carry & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3043 carry >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3044 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3045 if (carry) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3046 *pz += (digit)(carry & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3047 assert((carry >> PyLong_SHIFT) == 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3048 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3049 } |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
3050 else { /* a is not the same as b -- gradeschool int mult */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3051 for (i = 0; i < size_a; ++i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3052 twodigits carry = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3053 twodigits f = a->ob_digit[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3054 digit *pz = z->ob_digit + i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3055 digit *pb = b->ob_digit; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3056 digit *pbend = b->ob_digit + size_b; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3057 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3058 SIGCHECK({ |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3059 Py_DECREF(z); |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3060 return NULL; |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3061 }); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3062 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3063 while (pb < pbend) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3064 carry += *pz + *pb++ * f; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3065 *pz++ = (digit)(carry & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3066 carry >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3067 assert(carry <= PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3068 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3069 if (carry) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3070 *pz += (digit)(carry & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3071 assert((carry >> PyLong_SHIFT) == 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3072 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3073 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3074 return long_normalize(z); |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3075 } |
|
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3076 |
|
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3077 /* A helper for Karatsuba multiplication (k_mul). |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
3078 Takes an int "n" and an integer "size" representing the place to |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3079 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
|
3080 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
|
3081 the return values are >= 0. |
|
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3082 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
|
3083 */ |
|
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3084 static int |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3085 kmul_split(PyLongObject *n, |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3086 Py_ssize_t size, |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3087 PyLongObject **high, |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3088 PyLongObject **low) |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3089 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3090 PyLongObject *hi, *lo; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3091 Py_ssize_t size_lo, size_hi; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3092 const Py_ssize_t size_n = ABS(Py_SIZE(n)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3093 |
|
84022
41a2cbe23349
Reuse Py_MIN and Py_MAX macros: remove duplicate MIN/MAX macros
Victor Stinner <victor.stinner@gmail.com>
parents:
83433
diff
changeset
|
3094 size_lo = Py_MIN(size_n, size); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3095 size_hi = size_n - size_lo; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3096 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3097 if ((hi = _PyLong_New(size_hi)) == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3098 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3099 if ((lo = _PyLong_New(size_lo)) == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3100 Py_DECREF(hi); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3101 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3102 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3103 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3104 memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3105 memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3106 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3107 *high = long_normalize(hi); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3108 *low = long_normalize(lo); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3109 return 0; |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3110 } |
|
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3111 |
|
24773
801a44ab2aae
Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents:
24765
diff
changeset
|
3112 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
|
3113 |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3114 /* 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
|
3115 * 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
|
3116 * 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
|
3117 */ |
|
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3118 static PyLongObject * |
|
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3119 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
|
3120 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3121 Py_ssize_t asize = ABS(Py_SIZE(a)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3122 Py_ssize_t bsize = ABS(Py_SIZE(b)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3123 PyLongObject *ah = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3124 PyLongObject *al = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3125 PyLongObject *bh = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3126 PyLongObject *bl = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3127 PyLongObject *ret = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3128 PyLongObject *t1, *t2, *t3; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3129 Py_ssize_t shift; /* the number of digits we split off */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3130 Py_ssize_t i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3131 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3132 /* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3133 * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh + ah*bh + al*bl |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3134 * Then the original product is |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3135 * ah*bh*X*X + (k - ah*bh - al*bl)*X + al*bl |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3136 * By picking X to be a power of 2, "*X" is just shifting, and it's |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3137 * been reduced to 3 multiplies on numbers half the size. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3138 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3139 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3140 /* We want to split based on the larger number; fiddle so that b |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3141 * is largest. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3142 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3143 if (asize > bsize) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3144 t1 = a; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3145 a = b; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3146 b = t1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3147 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3148 i = asize; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3149 asize = bsize; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3150 bsize = i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3151 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3152 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3153 /* Use gradeschool math when either number is too small. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3154 i = a == b ? KARATSUBA_SQUARE_CUTOFF : KARATSUBA_CUTOFF; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3155 if (asize <= i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3156 if (asize == 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3157 return (PyLongObject *)PyLong_FromLong(0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3158 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3159 return x_mul(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3160 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3161 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3162 /* If a is small compared to b, splitting on b gives a degenerate |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3163 * case with ah==0, and Karatsuba may be (even much) less efficient |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3164 * than "grade school" then. However, we can still win, by viewing |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3165 * b as a string of "big digits", each of width a->ob_size. That |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3166 * leads to a sequence of balanced calls to k_mul. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3167 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3168 if (2 * asize <= bsize) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3169 return k_lopsided_mul(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3170 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3171 /* Split a & b into hi & lo pieces. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3172 shift = bsize >> 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3173 if (kmul_split(a, shift, &ah, &al) < 0) goto fail; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3174 assert(Py_SIZE(ah) > 0); /* the split isn't degenerate */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3175 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3176 if (a == b) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3177 bh = ah; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3178 bl = al; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3179 Py_INCREF(bh); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3180 Py_INCREF(bl); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3181 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3182 else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3183 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3184 /* The plan: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3185 * 1. Allocate result space (asize + bsize digits: that's always |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3186 * enough). |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3187 * 2. Compute ah*bh, and copy into result at 2*shift. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3188 * 3. Compute al*bl, and copy into result at 0. Note that this |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3189 * can't overlap with #2. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3190 * 4. Subtract al*bl from the result, starting at shift. This may |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3191 * underflow (borrow out of the high digit), but we don't care: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3192 * we're effectively doing unsigned arithmetic mod |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3193 * BASE**(sizea + sizeb), and so long as the *final* result fits, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3194 * borrows and carries out of the high digit can be ignored. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3195 * 5. Subtract ah*bh from the result, starting at shift. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3196 * 6. Compute (ah+al)*(bh+bl), and add it into the result starting |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3197 * at shift. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3198 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3199 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3200 /* 1. Allocate result space. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3201 ret = _PyLong_New(asize + bsize); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3202 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
|
3203 #ifdef Py_DEBUG |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3204 /* Fill with trash, to catch reference to uninitialized digits. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3205 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
|
3206 #endif |
|
24751
dbf6e563023b
x_mul(): This failed to normalize its result.
Tim Peters <tim.peters@gmail.com>
parents:
24750
diff
changeset
|
3207 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3208 /* 2. t1 <- ah*bh, and copy into high digits of result. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3209 if ((t1 = k_mul(ah, bh)) == NULL) goto fail; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3210 assert(Py_SIZE(t1) >= 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3211 assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3212 memcpy(ret->ob_digit + 2*shift, t1->ob_digit, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3213 Py_SIZE(t1) * sizeof(digit)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3214 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3215 /* Zero-out the digits higher than the ah*bh copy. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3216 i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3217 if (i) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3218 memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3219 i * sizeof(digit)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3220 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3221 /* 3. t2 <- al*bl, and copy into the low digits. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3222 if ((t2 = k_mul(al, bl)) == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3223 Py_DECREF(t1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3224 goto fail; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3225 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3226 assert(Py_SIZE(t2) >= 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3227 assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3228 memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3229 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3230 /* Zero out remaining digits. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3231 i = 2*shift - Py_SIZE(t2); /* number of uninitialized digits */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3232 if (i) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3233 memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3234 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3235 /* 4 & 5. Subtract ah*bh (t1) and al*bl (t2). We do al*bl first |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3236 * because it's fresher in cache. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3237 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3238 i = Py_SIZE(ret) - shift; /* # digits after shift */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3239 (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3240 Py_DECREF(t2); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3241 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3242 (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3243 Py_DECREF(t1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3244 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3245 /* 6. t3 <- (ah+al)(bh+bl), and add into result. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3246 if ((t1 = x_add(ah, al)) == NULL) goto fail; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3247 Py_DECREF(ah); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3248 Py_DECREF(al); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3249 ah = al = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3250 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3251 if (a == b) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3252 t2 = t1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3253 Py_INCREF(t2); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3254 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3255 else if ((t2 = x_add(bh, bl)) == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3256 Py_DECREF(t1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3257 goto fail; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3258 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3259 Py_DECREF(bh); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3260 Py_DECREF(bl); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3261 bh = bl = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3262 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3263 t3 = k_mul(t1, t2); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3264 Py_DECREF(t1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3265 Py_DECREF(t2); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3266 if (t3 == NULL) goto fail; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3267 assert(Py_SIZE(t3) >= 0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3268 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3269 /* Add t3. It's not obvious why we can't run out of room here. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3270 * See the (*) comment after this function. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3271 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3272 (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3273 Py_DECREF(t3); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3274 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3275 return long_normalize(ret); |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3276 |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3277 fail: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3278 Py_XDECREF(ret); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3279 Py_XDECREF(ah); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3280 Py_XDECREF(al); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3281 Py_XDECREF(bh); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3282 Py_XDECREF(bl); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3283 return NULL; |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3284 } |
|
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3285 |
|
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
|
3286 /* (*) 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
|
3287 |
|
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
|
3288 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
|
3289 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
|
3290 |
|
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
|
3291 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
|
3292 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
|
3293 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
|
3294 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
|
3295 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
|
3296 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
|
3297 |
|
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
|
3298 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
|
3299 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
|
3300 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
|
3301 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
|
3302 |
|
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
|
3303 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
|
3304 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
|
3305 |
|
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
|
3306 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
|
3307 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
|
3308 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
|
3309 |
|
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
|
3310 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
|
3311 |
|
10a4ec45549d
k_mul() comments: In honor of Dijkstra, made the proof that "t3 fits"
Tim Peters <tim.peters@gmail.com>
parents:
24845
diff
changeset
|
3312 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
|
3313 |
|
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
|
3314 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
|
3315 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
|
3316 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
|
3317 (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
|
3318 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
|
3319 asize is at least f(bsize/2)+1 digits, so this in turn reduces to whether 1 |
|
42334
e70cdce0e8b2
Merged revisions 56467-56482 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
42110
diff
changeset
|
3320 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
|
3321 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
|
3322 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
|
3323 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
|
3324 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
|
3325 |
|
24824
7c91d303c563
k_mul() comments: Simplified the simplified explanation of why ah*bh and
Tim Peters <tim.peters@gmail.com>
parents:
24821
diff
changeset
|
3326 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
|
3327 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
|
3328 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
|
3329 */ |
|
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
|
3330 |
|
24773
801a44ab2aae
Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents:
24765
diff
changeset
|
3331 /* 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
|
3332 * 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
|
3333 * 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
|
3334 * 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
|
3335 * also cache-friendly (we compute one double-width slice of the result |
|
68488
0991b40e895d
#11515: fix several typos. Patch by Piotr Kasprzyk.
Ezio Melotti <ezio.melotti@gmail.com>
parents:
61467
diff
changeset
|
3336 * 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
|
3337 * 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
|
3338 */ |
|
801a44ab2aae
Added new function k_lopsided_mul(), which is much more efficient than
Tim Peters <tim.peters@gmail.com>
parents:
24765
diff
changeset
|
3339 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
|
3340 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
|
3341 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3342 const Py_ssize_t asize = ABS(Py_SIZE(a)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3343 Py_ssize_t bsize = ABS(Py_SIZE(b)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3344 Py_ssize_t nbdone; /* # of b digits already multiplied */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3345 PyLongObject *ret; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3346 PyLongObject *bslice = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3347 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3348 assert(asize > KARATSUBA_CUTOFF); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3349 assert(2 * asize <= bsize); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3350 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3351 /* Allocate result space, and zero it out. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3352 ret = _PyLong_New(asize + bsize); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3353 if (ret == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3354 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3355 memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3356 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3357 /* Successive slices of b are copied into bslice. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3358 bslice = _PyLong_New(asize); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3359 if (bslice == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3360 goto fail; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3361 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3362 nbdone = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3363 while (bsize > 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3364 PyLongObject *product; |
|
84022
41a2cbe23349
Reuse Py_MIN and Py_MAX macros: remove duplicate MIN/MAX macros
Victor Stinner <victor.stinner@gmail.com>
parents:
83433
diff
changeset
|
3365 const Py_ssize_t nbtouse = Py_MIN(bsize, asize); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3366 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3367 /* Multiply the next slice of b by a. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3368 memcpy(bslice->ob_digit, b->ob_digit + nbdone, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3369 nbtouse * sizeof(digit)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3370 Py_SIZE(bslice) = nbtouse; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3371 product = k_mul(a, bslice); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3372 if (product == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3373 goto fail; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3374 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3375 /* Add into result. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3376 (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3377 product->ob_digit, Py_SIZE(product)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3378 Py_DECREF(product); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3379 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3380 bsize -= nbtouse; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3381 nbdone += nbtouse; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3382 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3383 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3384 Py_DECREF(bslice); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3385 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
|
3386 |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3387 fail: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3388 Py_DECREF(ret); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3389 Py_XDECREF(bslice); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3390 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
|
3391 } |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3392 |
|
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3393 static PyObject * |
| 43313 | 3394 long_mul(PyLongObject *a, PyLongObject *b) |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3395 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3396 PyLongObject *z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3397 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3398 CHECK_BINOP(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3399 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3400 /* fast path for single-digit multiplication */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3401 if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3402 stwodigits v = (stwodigits)(MEDIUM_VALUE(a)) * MEDIUM_VALUE(b); |
|
52215
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
3403 #ifdef HAVE_LONG_LONG |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3404 return PyLong_FromLongLong((PY_LONG_LONG)v); |
|
52215
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
3405 #else |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3406 /* if we don't have long long then we're almost certainly |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3407 using 15-bit digits, so v will fit in a long. In the |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3408 unlikely event that we're using 30-bit digits on a platform |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3409 without long long, a large v will just cause us to fall |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3410 through to the general multiplication code below. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3411 if (v >= LONG_MIN && v <= LONG_MAX) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3412 return PyLong_FromLong((long)v); |
|
52215
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
3413 #endif |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3414 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3415 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3416 z = k_mul(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3417 /* Negate if exactly one of the inputs is negative. */ |
|
84698
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
3418 if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) { |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
3419 _PyLong_Negate(&z); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
3420 if (z == NULL) |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
3421 return NULL; |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
3422 } |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3423 return (PyObject *)z; |
| 230 | 3424 } |
| 3425 | |
| 613 | 3426 /* The / and % operators are now defined in terms of divmod(). |
| 3427 The expression a mod b has the value a - b*floor(a/b). | |
| 3428 The long_divrem function gives the remainder after division of | |
| 230 | 3429 |a| by |b|, with the sign of a. This is also expressed |
| 3430 as a - b*trunc(a/b), if trunc truncates towards zero. | |
| 3431 Some examples: | |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3432 a b a rem b a mod b |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3433 13 10 3 3 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3434 -13 10 -3 7 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3435 13 -10 3 -7 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3436 -13 -10 -3 -3 |
| 230 | 3437 So, to get from rem to mod, we have to add b if a and b |
| 242 | 3438 have different signs. We then subtract one from the 'div' |
| 3439 part of the outcome to keep the invariant intact. */ | |
| 230 | 3440 |
|
33327
5452d4ecddd0
SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents:
33325
diff
changeset
|
3441 /* Compute |
|
5452d4ecddd0
SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents:
33325
diff
changeset
|
3442 * *pdiv, *pmod = divmod(v, w) |
|
5452d4ecddd0
SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents:
33325
diff
changeset
|
3443 * 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
|
3444 * 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
|
3445 * 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
|
3446 */ |
| 613 | 3447 static int |
|
24745
ba035f4b47c1
Cautious introduction of a patch that started from
Tim Peters <tim.peters@gmail.com>
parents:
24280
diff
changeset
|
3448 l_divmod(PyLongObject *v, PyLongObject *w, |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3449 PyLongObject **pdiv, PyLongObject **pmod) |
| 613 | 3450 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3451 PyLongObject *div, *mod; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3452 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3453 if (long_divrem(v, w, &div, &mod) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3454 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3455 if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3456 (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3457 PyLongObject *temp; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3458 PyLongObject *one; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3459 temp = (PyLongObject *) long_add(mod, w); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3460 Py_DECREF(mod); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3461 mod = temp; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3462 if (mod == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3463 Py_DECREF(div); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3464 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3465 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3466 one = (PyLongObject *) PyLong_FromLong(1L); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3467 if (one == NULL || |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3468 (temp = (PyLongObject *) long_sub(div, one)) == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3469 Py_DECREF(mod); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3470 Py_DECREF(div); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3471 Py_XDECREF(one); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3472 return -1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3473 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3474 Py_DECREF(one); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3475 Py_DECREF(div); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3476 div = temp; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3477 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3478 if (pdiv != NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3479 *pdiv = div; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3480 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3481 Py_DECREF(div); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3482 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3483 if (pmod != NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3484 *pmod = mod; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3485 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3486 Py_DECREF(mod); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3487 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3488 return 0; |
| 613 | 3489 } |
| 3490 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
3491 static PyObject * |
| 43313 | 3492 long_div(PyObject *a, PyObject *b) |
| 613 | 3493 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3494 PyLongObject *div; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3495 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3496 CHECK_BINOP(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3497 if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, NULL) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3498 div = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3499 return (PyObject *)div; |
| 613 | 3500 } |
| 3501 | |
|
57942
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3502 /* PyLong/PyLong -> float, with correctly rounded result. */ |
|
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3503 |
|
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3504 #define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT) |
|
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3505 #define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT) |
|
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3506 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
3507 static PyObject * |
|
57942
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3508 long_true_divide(PyObject *v, PyObject *w) |
|
19675
685dcae5c123
Move long_true_divide next to the other division routines (for clarity!).
Tim Peters <tim.peters@gmail.com>
parents:
19674
diff
changeset
|
3509 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3510 PyLongObject *a, *b, *x; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3511 Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3512 digit mask, low; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3513 int inexact, negate, a_is_small, b_is_small; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3514 double dx, result; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3515 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3516 CHECK_BINOP(v, w); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3517 a = (PyLongObject *)v; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3518 b = (PyLongObject *)w; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3519 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3520 /* |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3521 Method in a nutshell: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3522 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3523 0. reduce to case a, b > 0; filter out obvious underflow/overflow |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3524 1. choose a suitable integer 'shift' |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3525 2. use integer arithmetic to compute x = floor(2**-shift*a/b) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3526 3. adjust x for correct rounding |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3527 4. convert x to a double dx with the same value |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3528 5. return ldexp(dx, shift). |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3529 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3530 In more detail: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3531 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3532 0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3533 returns either 0.0 or -0.0, depending on the sign of b. For a and |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3534 b both nonzero, ignore signs of a and b, and add the sign back in |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3535 at the end. Now write a_bits and b_bits for the bit lengths of a |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3536 and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3537 for b). Then |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3538 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3539 2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1). |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3540 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3541 So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3542 so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP - |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3543 DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3544 the way, we can assume that |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3545 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3546 DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP. |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3547 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3548 1. The integer 'shift' is chosen so that x has the right number of |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3549 bits for a double, plus two or three extra bits that will be used |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3550 in the rounding decisions. Writing a_bits and b_bits for the |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3551 number of significant bits in a and b respectively, a |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3552 straightforward formula for shift is: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3553 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3554 shift = a_bits - b_bits - DBL_MANT_DIG - 2 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3555 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3556 This is fine in the usual case, but if a/b is smaller than the |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3557 smallest normal float then it can lead to double rounding on an |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3558 IEEE 754 platform, giving incorrectly rounded results. So we |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3559 adjust the formula slightly. The actual formula used is: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3560 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3561 shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3562 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3563 2. The quantity x is computed by first shifting a (left -shift bits |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3564 if shift <= 0, right shift bits if shift > 0) and then dividing by |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3565 b. For both the shift and the division, we keep track of whether |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3566 the result is inexact, in a flag 'inexact'; this information is |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3567 needed at the rounding stage. |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3568 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3569 With the choice of shift above, together with our assumption that |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3570 a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3571 that x >= 1. |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3572 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3573 3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3574 this with an exactly representable float of the form |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3575 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3576 round(x/2**extra_bits) * 2**(extra_bits+shift). |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3577 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3578 For float representability, we need x/2**extra_bits < |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3579 2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP - |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3580 DBL_MANT_DIG. This translates to the condition: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3581 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3582 extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3583 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3584 To round, we just modify the bottom digit of x in-place; this can |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3585 end up giving a digit with value > PyLONG_MASK, but that's not a |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3586 problem since digits can hold values up to 2*PyLONG_MASK+1. |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3587 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3588 With the original choices for shift above, extra_bits will always |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3589 be 2 or 3. Then rounding under the round-half-to-even rule, we |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3590 round up iff the most significant of the extra bits is 1, and |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3591 either: (a) the computation of x in step 2 had an inexact result, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3592 or (b) at least one other of the extra bits is 1, or (c) the least |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3593 significant bit of x (above those to be rounded) is 1. |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3594 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3595 4. Conversion to a double is straightforward; all floating-point |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3596 operations involved in the conversion are exact, so there's no |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3597 danger of rounding errors. |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3598 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3599 5. Use ldexp(x, shift) to compute x*2**shift, the final result. |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3600 The result will always be exactly representable as a double, except |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3601 in the case that it overflows. To avoid dependence on the exact |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3602 behaviour of ldexp on overflow, we check for overflow before |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3603 applying ldexp. The result of ldexp is adjusted for sign before |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3604 returning. |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3605 */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3606 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3607 /* Reduce to case where a and b are both positive. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3608 a_size = ABS(Py_SIZE(a)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3609 b_size = ABS(Py_SIZE(b)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3610 negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3611 if (b_size == 0) { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3612 PyErr_SetString(PyExc_ZeroDivisionError, |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3613 "division by zero"); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3614 goto error; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3615 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3616 if (a_size == 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3617 goto underflow_or_zero; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3618 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3619 /* Fast path for a and b small (exactly representable in a double). |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3620 Relies on floating-point division being correctly rounded; results |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3621 may be subject to double rounding on x86 machines that operate with |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3622 the x87 FPU set to 64-bit precision. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3623 a_is_small = a_size <= MANT_DIG_DIGITS || |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3624 (a_size == MANT_DIG_DIGITS+1 && |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3625 a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3626 b_is_small = b_size <= MANT_DIG_DIGITS || |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3627 (b_size == MANT_DIG_DIGITS+1 && |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3628 b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3629 if (a_is_small && b_is_small) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3630 double da, db; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3631 da = a->ob_digit[--a_size]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3632 while (a_size > 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3633 da = da * PyLong_BASE + a->ob_digit[--a_size]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3634 db = b->ob_digit[--b_size]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3635 while (b_size > 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3636 db = db * PyLong_BASE + b->ob_digit[--b_size]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3637 result = da / db; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3638 goto success; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3639 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3640 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3641 /* Catch obvious cases of underflow and overflow */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3642 diff = a_size - b_size; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3643 if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3644 /* Extreme overflow */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3645 goto overflow; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3646 else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3647 /* Extreme underflow */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3648 goto underflow_or_zero; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3649 /* Next line is now safe from overflowing a Py_ssize_t */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3650 diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) - |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3651 bits_in_digit(b->ob_digit[b_size - 1]); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3652 /* Now diff = a_bits - b_bits. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3653 if (diff > DBL_MAX_EXP) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3654 goto overflow; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3655 else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3656 goto underflow_or_zero; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3657 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3658 /* Choose value for shift; see comments for step 1 above. */ |
|
84022
41a2cbe23349
Reuse Py_MIN and Py_MAX macros: remove duplicate MIN/MAX macros
Victor Stinner <victor.stinner@gmail.com>
parents:
83433
diff
changeset
|
3659 shift = Py_MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3660 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3661 inexact = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3662 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3663 /* x = abs(a * 2**-shift) */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3664 if (shift <= 0) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3665 Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3666 digit rem; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3667 /* x = a << -shift */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3668 if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3669 /* In practice, it's probably impossible to end up |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3670 here. Both a and b would have to be enormous, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3671 using close to SIZE_T_MAX bytes of memory each. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3672 PyErr_SetString(PyExc_OverflowError, |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3673 "intermediate overflow during division"); |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3674 goto error; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3675 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3676 x = _PyLong_New(a_size + shift_digits + 1); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3677 if (x == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3678 goto error; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3679 for (i = 0; i < shift_digits; i++) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3680 x->ob_digit[i] = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3681 rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3682 a_size, -shift % PyLong_SHIFT); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3683 x->ob_digit[a_size + shift_digits] = rem; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3684 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3685 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3686 Py_ssize_t shift_digits = shift / PyLong_SHIFT; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3687 digit rem; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3688 /* x = a >> shift */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3689 assert(a_size >= shift_digits); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3690 x = _PyLong_New(a_size - shift_digits); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3691 if (x == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3692 goto error; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3693 rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3694 a_size - shift_digits, shift % PyLong_SHIFT); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3695 /* set inexact if any of the bits shifted out is nonzero */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3696 if (rem) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3697 inexact = 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3698 while (!inexact && shift_digits > 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3699 if (a->ob_digit[--shift_digits]) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3700 inexact = 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3701 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3702 long_normalize(x); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3703 x_size = Py_SIZE(x); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3704 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3705 /* x //= b. If the remainder is nonzero, set inexact. We own the only |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3706 reference to x, so it's safe to modify it in-place. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3707 if (b_size == 1) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3708 digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3709 b->ob_digit[0]); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3710 long_normalize(x); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3711 if (rem) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3712 inexact = 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3713 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3714 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3715 PyLongObject *div, *rem; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3716 div = x_divrem(x, b, &rem); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3717 Py_DECREF(x); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3718 x = div; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3719 if (x == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3720 goto error; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3721 if (Py_SIZE(rem)) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3722 inexact = 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3723 Py_DECREF(rem); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3724 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3725 x_size = ABS(Py_SIZE(x)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3726 assert(x_size > 0); /* result of division is never zero */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3727 x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3728 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3729 /* The number of extra bits that have to be rounded away. */ |
|
84022
41a2cbe23349
Reuse Py_MIN and Py_MAX macros: remove duplicate MIN/MAX macros
Victor Stinner <victor.stinner@gmail.com>
parents:
83433
diff
changeset
|
3730 extra_bits = Py_MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3731 assert(extra_bits == 2 || extra_bits == 3); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3732 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3733 /* Round by directly modifying the low digit of x. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3734 mask = (digit)1 << (extra_bits - 1); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3735 low = x->ob_digit[0] | inexact; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3736 if (low & mask && low & (3*mask-1)) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3737 low += mask; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3738 x->ob_digit[0] = low & ~(mask-1U); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3739 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3740 /* Convert x to a double dx; the conversion is exact. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3741 dx = x->ob_digit[--x_size]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3742 while (x_size > 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3743 dx = dx * PyLong_BASE + x->ob_digit[--x_size]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3744 Py_DECREF(x); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3745 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3746 /* Check whether ldexp result will overflow a double. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3747 if (shift + x_bits >= DBL_MAX_EXP && |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3748 (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, (int)x_bits))) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3749 goto overflow; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3750 result = ldexp(dx, (int)shift); |
|
57942
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3751 |
|
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3752 success: |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3753 return PyFloat_FromDouble(negate ? -result : result); |
|
57942
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3754 |
|
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3755 underflow_or_zero: |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3756 return PyFloat_FromDouble(negate ? -0.0 : 0.0); |
|
57942
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3757 |
|
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3758 overflow: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3759 PyErr_SetString(PyExc_OverflowError, |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
3760 "integer division result too large for a float"); |
|
57942
aaa5ab7b942a
Merged revisions 77062 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
57858
diff
changeset
|
3761 error: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3762 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
|
3763 } |
|
685dcae5c123
Move long_true_divide next to the other division routines (for clarity!).
Tim Peters <tim.peters@gmail.com>
parents:
19674
diff
changeset
|
3764 |
|
685dcae5c123
Move long_true_divide next to the other division routines (for clarity!).
Tim Peters <tim.peters@gmail.com>
parents:
19674
diff
changeset
|
3765 static PyObject * |
| 43313 | 3766 long_mod(PyObject *a, PyObject *b) |
| 613 | 3767 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3768 PyLongObject *mod; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3769 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3770 CHECK_BINOP(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3771 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3772 if (l_divmod((PyLongObject*)a, (PyLongObject*)b, NULL, &mod) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3773 mod = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3774 return (PyObject *)mod; |
| 613 | 3775 } |
| 3776 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
3777 static PyObject * |
| 43313 | 3778 long_divmod(PyObject *a, PyObject *b) |
| 230 | 3779 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3780 PyLongObject *div, *mod; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3781 PyObject *z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3782 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3783 CHECK_BINOP(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3784 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3785 if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, &mod) < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3786 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3787 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3788 z = PyTuple_New(2); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3789 if (z != NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3790 PyTuple_SetItem(z, 0, (PyObject *) div); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3791 PyTuple_SetItem(z, 1, (PyObject *) mod); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3792 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3793 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3794 Py_DECREF(div); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3795 Py_DECREF(mod); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3796 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3797 return z; |
| 230 | 3798 } |
| 3799 | |
|
33327
5452d4ecddd0
SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents:
33325
diff
changeset
|
3800 /* pow(v, w, x) */ |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
3801 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
|
3802 long_pow(PyObject *v, PyObject *w, PyObject *x) |
| 230 | 3803 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3804 PyLongObject *a, *b, *c; /* a,b,c = v,w,x */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3805 int negativeOutput = 0; /* if x<0 return negative output */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3806 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3807 PyLongObject *z = NULL; /* accumulated result */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3808 Py_ssize_t i, j, k; /* counters */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3809 PyLongObject *temp = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3810 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3811 /* 5-ary values. If the exponent is large enough, table is |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3812 * precomputed so that table[i] == a**i % c for i in range(32). |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3813 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3814 PyLongObject *table[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3815 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3816 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3817 /* a, b, c = v, w, x */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3818 CHECK_BINOP(v, w); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3819 a = (PyLongObject*)v; Py_INCREF(a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3820 b = (PyLongObject*)w; Py_INCREF(b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3821 if (PyLong_Check(x)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3822 c = (PyLongObject *)x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3823 Py_INCREF(x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3824 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3825 else if (x == Py_None) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3826 c = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3827 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3828 Py_DECREF(a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3829 Py_DECREF(b); |
|
71810
d0b0fcbb40db
Replace Py_NotImplemented returns with the macro form Py_RETURN_NOTIMPLEMENTED.
Brian Curtin <brian@python.org>
parents:
68586
diff
changeset
|
3830 Py_RETURN_NOTIMPLEMENTED; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3831 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3832 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3833 if (Py_SIZE(b) < 0) { /* if exponent is negative */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3834 if (c) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3835 PyErr_SetString(PyExc_TypeError, "pow() 2nd argument " |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3836 "cannot be negative when 3rd argument specified"); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3837 goto Error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3838 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3839 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3840 /* else return a float. This works because we know |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3841 that this calls float_pow() which converts its |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3842 arguments to double. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3843 Py_DECREF(a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3844 Py_DECREF(b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3845 return PyFloat_Type.tp_as_number->nb_power(v, w, x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3846 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3847 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3848 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3849 if (c) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3850 /* if modulus == 0: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3851 raise ValueError() */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3852 if (Py_SIZE(c) == 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3853 PyErr_SetString(PyExc_ValueError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3854 "pow() 3rd argument cannot be 0"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3855 goto Error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3856 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3857 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3858 /* if modulus < 0: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3859 negativeOutput = True |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3860 modulus = -modulus */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3861 if (Py_SIZE(c) < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3862 negativeOutput = 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3863 temp = (PyLongObject *)_PyLong_Copy(c); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3864 if (temp == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3865 goto Error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3866 Py_DECREF(c); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3867 c = temp; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3868 temp = NULL; |
|
84698
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
3869 _PyLong_Negate(&c); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
3870 if (c == NULL) |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
3871 goto Error; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3872 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3873 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3874 /* if modulus == 1: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3875 return 0 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3876 if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3877 z = (PyLongObject *)PyLong_FromLong(0L); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3878 goto Done; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3879 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3880 |
|
85981
f34c59494420
Issue #19171: speed some cases of 3-argument long pow().
Tim Peters <tim@python.org>
parents:
85418
diff
changeset
|
3881 /* Reduce base by modulus in some cases: |
|
f34c59494420
Issue #19171: speed some cases of 3-argument long pow().
Tim Peters <tim@python.org>
parents:
85418
diff
changeset
|
3882 1. If base < 0. Forcing the base non-negative makes things easier. |
|
f34c59494420
Issue #19171: speed some cases of 3-argument long pow().
Tim Peters <tim@python.org>
parents:
85418
diff
changeset
|
3883 2. If base is obviously larger than the modulus. The "small |
|
f34c59494420
Issue #19171: speed some cases of 3-argument long pow().
Tim Peters <tim@python.org>
parents:
85418
diff
changeset
|
3884 exponent" case later can multiply directly by base repeatedly, |
|
f34c59494420
Issue #19171: speed some cases of 3-argument long pow().
Tim Peters <tim@python.org>
parents:
85418
diff
changeset
|
3885 while the "large exponent" case multiplies directly by base 31 |
|
f34c59494420
Issue #19171: speed some cases of 3-argument long pow().
Tim Peters <tim@python.org>
parents:
85418
diff
changeset
|
3886 times. It can be unboundedly faster to multiply by |
|
f34c59494420
Issue #19171: speed some cases of 3-argument long pow().
Tim Peters <tim@python.org>
parents:
85418
diff
changeset
|
3887 base % modulus instead. |
|
f34c59494420
Issue #19171: speed some cases of 3-argument long pow().
Tim Peters <tim@python.org>
parents:
85418
diff
changeset
|
3888 We could _always_ do this reduction, but l_divmod() isn't cheap, |
|
f34c59494420
Issue #19171: speed some cases of 3-argument long pow().
Tim Peters <tim@python.org>
parents:
85418
diff
changeset
|
3889 so we only do it when it buys something. */ |
|
f34c59494420
Issue #19171: speed some cases of 3-argument long pow().
Tim Peters <tim@python.org>
parents:
85418
diff
changeset
|
3890 if (Py_SIZE(a) < 0 || Py_SIZE(a) > Py_SIZE(c)) { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3891 if (l_divmod(a, c, NULL, &temp) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3892 goto Error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3893 Py_DECREF(a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3894 a = temp; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3895 temp = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3896 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3897 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3898 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3899 /* At this point a, b, and c are guaranteed non-negative UNLESS |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3900 c is NULL, in which case a may be negative. */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3901 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3902 z = (PyLongObject *)PyLong_FromLong(1L); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3903 if (z == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3904 goto Error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3905 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3906 /* Perform a modular reduction, X = X % c, but leave X alone if c |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3907 * is NULL. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3908 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3909 #define REDUCE(X) \ |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3910 do { \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3911 if (c != NULL) { \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3912 if (l_divmod(X, c, NULL, &temp) < 0) \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3913 goto Error; \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3914 Py_XDECREF(X); \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3915 X = temp; \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3916 temp = NULL; \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3917 } \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3918 } while(0) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3919 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3920 /* Multiply two values, then reduce the result: |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3921 result = X*Y % c. If c is NULL, skip the mod. */ |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3922 #define MULT(X, Y, result) \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3923 do { \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3924 temp = (PyLongObject *)long_mul(X, Y); \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3925 if (temp == NULL) \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3926 goto Error; \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3927 Py_XDECREF(result); \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3928 result = temp; \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3929 temp = NULL; \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3930 REDUCE(result); \ |
|
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3931 } while(0) |
|
33327
5452d4ecddd0
SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents:
33325
diff
changeset
|
3932 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3933 if (Py_SIZE(b) <= FIVEARY_CUTOFF) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3934 /* Left-to-right binary exponentiation (HAC Algorithm 14.79) */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3935 /* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3936 for (i = Py_SIZE(b) - 1; i >= 0; --i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3937 digit bi = b->ob_digit[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3938 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3939 for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) { |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3940 MULT(z, z, z); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3941 if (bi & j) |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3942 MULT(z, a, z); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3943 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3944 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3945 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3946 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3947 /* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3948 Py_INCREF(z); /* still holds 1L */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3949 table[0] = z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3950 for (i = 1; i < 32; ++i) |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3951 MULT(table[i-1], a, table[i]); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3952 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3953 for (i = Py_SIZE(b) - 1; i >= 0; --i) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3954 const digit bi = b->ob_digit[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3955 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3956 for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3957 const int index = (bi >> j) & 0x1f; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3958 for (k = 0; k < 5; ++k) |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3959 MULT(z, z, z); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3960 if (index) |
|
61492
f1358aa33a6e
Merged revisions 81037 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61491
diff
changeset
|
3961 MULT(z, table[index], z); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3962 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3963 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3964 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3965 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3966 if (negativeOutput && (Py_SIZE(z) != 0)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3967 temp = (PyLongObject *)long_sub(z, c); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3968 if (temp == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3969 goto Error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3970 Py_DECREF(z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3971 z = temp; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3972 temp = NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3973 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3974 goto Done; |
|
33327
5452d4ecddd0
SF patch 936813: fast modular exponentiation
Tim Peters <tim.peters@gmail.com>
parents:
33325
diff
changeset
|
3975 |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3976 Error: |
|
84698
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
3977 Py_CLEAR(z); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3978 /* fall through */ |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
3979 Done: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3980 if (Py_SIZE(b) > FIVEARY_CUTOFF) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3981 for (i = 0; i < 32; ++i) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3982 Py_XDECREF(table[i]); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3983 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3984 Py_DECREF(a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3985 Py_DECREF(b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3986 Py_XDECREF(c); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3987 Py_XDECREF(temp); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3988 return (PyObject *)z; |
| 230 | 3989 } |
| 3990 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
3991 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
|
3992 long_invert(PyLongObject *v) |
| 230 | 3993 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3994 /* Implement ~x as -(x+1) */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3995 PyLongObject *x; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3996 PyLongObject *w; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3997 if (ABS(Py_SIZE(v)) <=1) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3998 return PyLong_FromLong(-(MEDIUM_VALUE(v)+1)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
3999 w = (PyLongObject *)PyLong_FromLong(1L); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4000 if (w == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4001 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4002 x = (PyLongObject *) long_add(v, w); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4003 Py_DECREF(w); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4004 if (x == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4005 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4006 Py_SIZE(x) = -(Py_SIZE(x)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4007 return (PyObject *)maybe_small_long(x); |
| 230 | 4008 } |
| 4009 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4010 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
|
4011 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
|
4012 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4013 PyLongObject *z; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4014 if (ABS(Py_SIZE(v)) <= 1) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4015 return PyLong_FromLong(-MEDIUM_VALUE(v)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4016 z = (PyLongObject *)_PyLong_Copy(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4017 if (z != NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4018 Py_SIZE(z) = -(Py_SIZE(v)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4019 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
|
4020 } |
|
9f85beb1f7c8
Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents:
406
diff
changeset
|
4021 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4022 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
|
4023 long_abs(PyLongObject *v) |
| 230 | 4024 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4025 if (Py_SIZE(v) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4026 return long_neg(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4027 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4028 return long_long((PyObject *)v); |
| 230 | 4029 } |
| 4030 | |
| 242 | 4031 static int |
|
40401
88133417dfd0
- patch #1600346 submitted by Tomer Filiba
Jack Diederich <jackdied@gmail.com>
parents:
39703
diff
changeset
|
4032 long_bool(PyLongObject *v) |
| 242 | 4033 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4034 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
|
4035 } |
|
9f85beb1f7c8
Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents:
406
diff
changeset
|
4036 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4037 static PyObject * |
| 43313 | 4038 long_rshift(PyLongObject *a, 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
|
4039 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4040 PyLongObject *z = NULL; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4041 Py_ssize_t shiftby, newsize, wordshift, loshift, hishift, i, j; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4042 digit lomask, himask; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4043 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4044 CHECK_BINOP(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4045 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4046 if (Py_SIZE(a) < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4047 /* Right shifting negative numbers is harder */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4048 PyLongObject *a1, *a2; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4049 a1 = (PyLongObject *) long_invert(a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4050 if (a1 == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4051 goto rshift_error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4052 a2 = (PyLongObject *) long_rshift(a1, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4053 Py_DECREF(a1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4054 if (a2 == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4055 goto rshift_error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4056 z = (PyLongObject *) long_invert(a2); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4057 Py_DECREF(a2); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4058 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4059 else { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4060 shiftby = PyLong_AsSsize_t((PyObject *)b); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4061 if (shiftby == -1L && PyErr_Occurred()) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4062 goto rshift_error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4063 if (shiftby < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4064 PyErr_SetString(PyExc_ValueError, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4065 "negative shift count"); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4066 goto rshift_error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4067 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4068 wordshift = shiftby / PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4069 newsize = ABS(Py_SIZE(a)) - wordshift; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4070 if (newsize <= 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4071 return PyLong_FromLong(0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4072 loshift = shiftby % PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4073 hishift = PyLong_SHIFT - loshift; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4074 lomask = ((digit)1 << hishift) - 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4075 himask = PyLong_MASK ^ lomask; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4076 z = _PyLong_New(newsize); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4077 if (z == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4078 goto rshift_error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4079 if (Py_SIZE(a) < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4080 Py_SIZE(z) = -(Py_SIZE(z)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4081 for (i = 0, j = wordshift; i < newsize; i++, j++) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4082 z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4083 if (i+1 < newsize) |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4084 z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4085 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4086 z = long_normalize(z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4087 } |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4088 rshift_error: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4089 return (PyObject *) maybe_small_long(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
|
4090 |
|
443
9f85beb1f7c8
Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents:
406
diff
changeset
|
4091 } |
|
9f85beb1f7c8
Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents:
406
diff
changeset
|
4092 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4093 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
|
4094 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
|
4095 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4096 /* This version due to Tim Peters */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4097 PyLongObject *a = (PyLongObject*)v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4098 PyLongObject *b = (PyLongObject*)w; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4099 PyLongObject *z = NULL; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4100 Py_ssize_t shiftby, oldsize, newsize, wordshift, remshift, i, j; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4101 twodigits accum; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4102 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4103 CHECK_BINOP(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4104 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4105 shiftby = PyLong_AsSsize_t((PyObject *)b); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4106 if (shiftby == -1L && PyErr_Occurred()) |
|
84698
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
4107 return NULL; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4108 if (shiftby < 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4109 PyErr_SetString(PyExc_ValueError, "negative shift count"); |
|
84698
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
4110 return NULL; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4111 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4112 /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4113 wordshift = shiftby / PyLong_SHIFT; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4114 remshift = shiftby - wordshift * PyLong_SHIFT; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4115 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4116 oldsize = ABS(Py_SIZE(a)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4117 newsize = oldsize + wordshift; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4118 if (remshift) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4119 ++newsize; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4120 z = _PyLong_New(newsize); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4121 if (z == NULL) |
|
84698
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
4122 return NULL; |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
4123 if (Py_SIZE(a) < 0) { |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
4124 assert(Py_REFCNT(z) == 1); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
4125 Py_SIZE(z) = -Py_SIZE(z); |
|
736514fb7b52
Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
Victor Stinner <victor.stinner@gmail.com>
parents:
84022
diff
changeset
|
4126 } |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4127 for (i = 0; i < wordshift; i++) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4128 z->ob_digit[i] = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4129 accum = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4130 for (i = wordshift, j = 0; j < oldsize; i++, j++) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4131 accum |= (twodigits)a->ob_digit[j] << remshift; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4132 z->ob_digit[i] = (digit)(accum & PyLong_MASK); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4133 accum >>= PyLong_SHIFT; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4134 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4135 if (remshift) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4136 z->ob_digit[newsize-1] = (digit)accum; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4137 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4138 assert(!accum); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4139 z = long_normalize(z); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4140 return (PyObject *) maybe_small_long(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
|
4141 } |
|
9f85beb1f7c8
Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents:
406
diff
changeset
|
4142 |
|
56734
4834a4285411
Merged revisions 75697 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
56264
diff
changeset
|
4143 /* Compute two's complement of digit vector a[0:m], writing result to |
|
4834a4285411
Merged revisions 75697 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
56264
diff
changeset
|
4144 z[0:m]. The digit vector a need not be normalized, but should not |
|
4834a4285411
Merged revisions 75697 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
56264
diff
changeset
|
4145 be entirely zero. a and z may point to the same digit vector. */ |
|
4834a4285411
Merged revisions 75697 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
56264
diff
changeset
|
4146 |
|
4834a4285411
Merged revisions 75697 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
56264
diff
changeset
|
4147 static void |
|
4834a4285411
Merged revisions 75697 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
56264
diff
changeset
|
4148 v_complement(digit *z, digit *a, Py_ssize_t m) |
|
4834a4285411
Merged revisions 75697 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
56264
diff
changeset
|
4149 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4150 Py_ssize_t i; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4151 digit carry = 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4152 for (i = 0; i < m; ++i) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4153 carry += a[i] ^ PyLong_MASK; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4154 z[i] = carry & PyLong_MASK; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4155 carry >>= PyLong_SHIFT; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4156 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4157 assert(carry == 0); |
|
56734
4834a4285411
Merged revisions 75697 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
56264
diff
changeset
|
4158 } |
|
590
f11fae8ee1e4
Changed to 2's complement bitwise ops. Got rid of ZABS etc.
Guido van Rossum <guido@python.org>
parents:
546
diff
changeset
|
4159 |
|
f11fae8ee1e4
Changed to 2's complement bitwise ops. Got rid of ZABS etc.
Guido van Rossum <guido@python.org>
parents:
546
diff
changeset
|
4160 /* 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
|
4161 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4162 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
|
4163 long_bitwise(PyLongObject *a, |
|
81078
3b5fdb5bc597
use more specific type
Benjamin Peterson <benjamin@python.org>
parents:
81057
diff
changeset
|
4164 char op, /* '&', '|', '^' */ |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4165 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
|
4166 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4167 int nega, negb, negz; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4168 Py_ssize_t size_a, size_b, size_z, i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4169 PyLongObject *z; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4170 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4171 /* Bitwise operations for negative numbers operate as though |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4172 on a two's complement representation. So convert arguments |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4173 from sign-magnitude to two's complement, and convert the |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4174 result back to sign-magnitude at the end. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4175 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4176 /* If a is negative, replace it by its two's complement. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4177 size_a = ABS(Py_SIZE(a)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4178 nega = Py_SIZE(a) < 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4179 if (nega) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4180 z = _PyLong_New(size_a); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4181 if (z == NULL) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4182 return NULL; |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4183 v_complement(z->ob_digit, a->ob_digit, size_a); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4184 a = z; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4185 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4186 else |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4187 /* Keep reference count consistent. */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4188 Py_INCREF(a); |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4189 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4190 /* Same for b. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4191 size_b = ABS(Py_SIZE(b)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4192 negb = Py_SIZE(b) < 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4193 if (negb) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4194 z = _PyLong_New(size_b); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4195 if (z == NULL) { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4196 Py_DECREF(a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4197 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4198 } |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4199 v_complement(z->ob_digit, b->ob_digit, size_b); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4200 b = z; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4201 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4202 else |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4203 Py_INCREF(b); |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4204 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4205 /* Swap a and b if necessary to ensure size_a >= size_b. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4206 if (size_a < size_b) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4207 z = a; a = b; b = z; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4208 size_z = size_a; size_a = size_b; size_b = size_z; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4209 negz = nega; nega = negb; negb = negz; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4210 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4211 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4212 /* JRH: The original logic here was to allocate the result value (z) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4213 as the longer of the two operands. However, there are some cases |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4214 where the result is guaranteed to be shorter than that: AND of two |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4215 positives, OR of two negatives: use the shorter number. AND with |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4216 mixed signs: use the positive number. OR with mixed signs: use the |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4217 negative number. |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4218 */ |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4219 switch (op) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4220 case '^': |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4221 negz = nega ^ negb; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4222 size_z = size_a; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4223 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4224 case '&': |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4225 negz = nega & negb; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4226 size_z = negb ? size_a : size_b; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4227 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4228 case '|': |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4229 negz = nega | negb; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4230 size_z = negb ? size_b : size_a; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4231 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4232 default: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4233 PyErr_BadArgument(); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4234 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4235 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4236 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4237 /* We allow an extra digit if z is negative, to make sure that |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4238 the final two's complement of z doesn't overflow. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4239 z = _PyLong_New(size_z + negz); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4240 if (z == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4241 Py_DECREF(a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4242 Py_DECREF(b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4243 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4244 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4245 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4246 /* Compute digits for overlap of a and b. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4247 switch(op) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4248 case '&': |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4249 for (i = 0; i < size_b; ++i) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4250 z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4251 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4252 case '|': |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4253 for (i = 0; i < size_b; ++i) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4254 z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4255 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4256 case '^': |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4257 for (i = 0; i < size_b; ++i) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4258 z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4259 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4260 default: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4261 PyErr_BadArgument(); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4262 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4263 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4264 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4265 /* Copy any remaining digits of a, inverting if necessary. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4266 if (op == '^' && negb) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4267 for (; i < size_z; ++i) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4268 z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4269 else if (i < size_z) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4270 memcpy(&z->ob_digit[i], &a->ob_digit[i], |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4271 (size_z-i)*sizeof(digit)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4272 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4273 /* Complement result if negative. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4274 if (negz) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4275 Py_SIZE(z) = -(Py_SIZE(z)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4276 z->ob_digit[size_z] = PyLong_MASK; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4277 v_complement(z->ob_digit, z->ob_digit, size_z+1); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4278 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4279 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4280 Py_DECREF(a); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4281 Py_DECREF(b); |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4282 return (PyObject *)maybe_small_long(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
|
4283 } |
|
9f85beb1f7c8
Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents:
406
diff
changeset
|
4284 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4285 static PyObject * |
| 43313 | 4286 long_and(PyObject *a, PyObject *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
|
4287 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4288 PyObject *c; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4289 CHECK_BINOP(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4290 c = long_bitwise((PyLongObject*)a, '&', (PyLongObject*)b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4291 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
|
4292 } |
|
9f85beb1f7c8
Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents:
406
diff
changeset
|
4293 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4294 static PyObject * |
| 43313 | 4295 long_xor(PyObject *a, PyObject *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
|
4296 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4297 PyObject *c; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4298 CHECK_BINOP(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4299 c = long_bitwise((PyLongObject*)a, '^', (PyLongObject*)b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4300 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
|
4301 } |
|
9f85beb1f7c8
Made the sign use one's complement; implemented shifting and masking operators.
Guido van Rossum <guido@python.org>
parents:
406
diff
changeset
|
4302 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4303 static PyObject * |
| 43313 | 4304 long_or(PyObject *a, PyObject *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
|
4305 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4306 PyObject *c; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4307 CHECK_BINOP(a, b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4308 c = long_bitwise((PyLongObject*)a, '|', (PyLongObject*)b); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4309 return c; |
| 242 | 4310 } |
| 4311 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4312 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
|
4313 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
|
4314 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4315 if (PyLong_CheckExact(v)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4316 Py_INCREF(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4317 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4318 v = _PyLong_Copy((PyLongObject *)v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4319 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
|
4320 } |
|
d31ddc66b1b5
Change int() so that passing a string, unicode, float or long argument
Walter Dörwald <walter@livinglogic.de>
parents:
26081
diff
changeset
|
4321 |
|
d31ddc66b1b5
Change int() so that passing a string, unicode, float or long argument
Walter Dörwald <walter@livinglogic.de>
parents:
26081
diff
changeset
|
4322 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
|
4323 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
|
4324 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4325 double result; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4326 result = PyLong_AsDouble(v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4327 if (result == -1.0 && PyErr_Occurred()) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4328 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4329 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
|
4330 } |
|
2ed511171809
Made builtins int(), long(), float(), oct() and hex() more generic.
Guido van Rossum <guido@python.org>
parents:
958
diff
changeset
|
4331 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4332 static PyObject * |
|
19552
6c30d20d27f2
Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents:
19343
diff
changeset
|
4333 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
|
4334 |
|
18933
09df3254b49d
Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents:
18607
diff
changeset
|
4335 static PyObject * |
|
09df3254b49d
Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents:
18607
diff
changeset
|
4336 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
|
4337 { |
|
61940
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4338 PyObject *obase = NULL, *x = NULL; |
|
81057
60f7197f991f
Test for issue16772 and redoes the previous fix to accept __index__-aware
Gregory P. Smith <greg@krypto.org>
parents:
81048
diff
changeset
|
4339 Py_ssize_t base; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4340 static char *kwlist[] = {"x", "base", 0}; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4341 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4342 if (type != &PyLong_Type) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4343 return long_subtype_new(type, args, kwds); /* Wimp out */ |
|
61940
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4344 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:int", kwlist, |
|
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4345 &x, &obase)) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4346 return NULL; |
|
81124
e4ea38a92c4d
Issue #16761: Raise TypeError when int() called with base argument only.
Serhiy Storchaka <storchaka@gmail.com>
parents:
79815
diff
changeset
|
4347 if (x == NULL) { |
|
e4ea38a92c4d
Issue #16761: Raise TypeError when int() called with base argument only.
Serhiy Storchaka <storchaka@gmail.com>
parents:
79815
diff
changeset
|
4348 if (obase != NULL) { |
|
e4ea38a92c4d
Issue #16761: Raise TypeError when int() called with base argument only.
Serhiy Storchaka <storchaka@gmail.com>
parents:
79815
diff
changeset
|
4349 PyErr_SetString(PyExc_TypeError, |
|
e4ea38a92c4d
Issue #16761: Raise TypeError when int() called with base argument only.
Serhiy Storchaka <storchaka@gmail.com>
parents:
79815
diff
changeset
|
4350 "int() missing string argument"); |
|
e4ea38a92c4d
Issue #16761: Raise TypeError when int() called with base argument only.
Serhiy Storchaka <storchaka@gmail.com>
parents:
79815
diff
changeset
|
4351 return NULL; |
|
e4ea38a92c4d
Issue #16761: Raise TypeError when int() called with base argument only.
Serhiy Storchaka <storchaka@gmail.com>
parents:
79815
diff
changeset
|
4352 } |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4353 return PyLong_FromLong(0L); |
|
81124
e4ea38a92c4d
Issue #16761: Raise TypeError when int() called with base argument only.
Serhiy Storchaka <storchaka@gmail.com>
parents:
79815
diff
changeset
|
4354 } |
|
61940
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4355 if (obase == NULL) |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4356 return PyNumber_Long(x); |
|
61940
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4357 |
|
81057
60f7197f991f
Test for issue16772 and redoes the previous fix to accept __index__-aware
Gregory P. Smith <greg@krypto.org>
parents:
81048
diff
changeset
|
4358 base = PyNumber_AsSsize_t(obase, NULL); |
|
61940
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4359 if (base == -1 && PyErr_Occurred()) |
|
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4360 return NULL; |
|
81057
60f7197f991f
Test for issue16772 and redoes the previous fix to accept __index__-aware
Gregory P. Smith <greg@krypto.org>
parents:
81048
diff
changeset
|
4361 if ((base != 0 && base < 2) || base > 36) { |
|
61940
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4362 PyErr_SetString(PyExc_ValueError, |
|
81124
e4ea38a92c4d
Issue #16761: Raise TypeError when int() called with base argument only.
Serhiy Storchaka <storchaka@gmail.com>
parents:
79815
diff
changeset
|
4363 "int() base must be >= 2 and <= 36"); |
|
61940
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4364 return NULL; |
|
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4365 } |
|
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4366 |
|
c42ffb3d63af
Issue #2844: Make int('42', n) consistently raise ValueError for
Mark Dickinson <dickinsm@gmail.com>
parents:
61924
diff
changeset
|
4367 if (PyUnicode_Check(x)) |
| 72475 | 4368 return PyLong_FromUnicodeObject(x, (int)base); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4369 else if (PyByteArray_Check(x) || PyBytes_Check(x)) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4370 char *string; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4371 if (PyByteArray_Check(x)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4372 string = PyByteArray_AS_STRING(x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4373 else |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4374 string = PyBytes_AS_STRING(x); |
|
84995
ecc8512b427d
Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents:
82111
diff
changeset
|
4375 return _PyLong_FromBytes(string, Py_SIZE(x), (int)base); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4376 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4377 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4378 PyErr_SetString(PyExc_TypeError, |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4379 "int() can't convert non-string with explicit base"); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4380 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4381 } |
|
18933
09df3254b49d
Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents:
18607
diff
changeset
|
4382 } |
|
09df3254b49d
Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents:
18607
diff
changeset
|
4383 |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
4384 /* Wimpy, slow approach to tp_new calls for subtypes of int: |
|
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
4385 first create a regular int from whatever arguments we got, |
|
19552
6c30d20d27f2
Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents:
19343
diff
changeset
|
4386 then allocate a subtype instance and initialize it from |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
4387 the regular int. The regular int is then thrown away. |
|
19552
6c30d20d27f2
Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents:
19343
diff
changeset
|
4388 */ |
|
6c30d20d27f2
Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents:
19343
diff
changeset
|
4389 static PyObject * |
|
6c30d20d27f2
Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents:
19343
diff
changeset
|
4390 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
|
4391 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4392 PyLongObject *tmp, *newobj; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4393 Py_ssize_t i, n; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4394 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4395 assert(PyType_IsSubtype(type, &PyLong_Type)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4396 tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4397 if (tmp == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4398 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4399 assert(PyLong_CheckExact(tmp)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4400 n = Py_SIZE(tmp); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4401 if (n < 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4402 n = -n; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4403 newobj = (PyLongObject *)type->tp_alloc(type, n); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4404 if (newobj == NULL) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4405 Py_DECREF(tmp); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4406 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4407 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4408 assert(PyLong_Check(newobj)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4409 Py_SIZE(newobj) = Py_SIZE(tmp); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4410 for (i = 0; i < n; i++) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4411 newobj->ob_digit[i] = tmp->ob_digit[i]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4412 Py_DECREF(tmp); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4413 return (PyObject *)newobj; |
|
19552
6c30d20d27f2
Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents:
19343
diff
changeset
|
4414 } |
|
6c30d20d27f2
Make int, long and float subclassable.
Guido van Rossum <guido@python.org>
parents:
19343
diff
changeset
|
4415 |
|
27521
17bfd5dbc0f1
Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents:
27487
diff
changeset
|
4416 static PyObject * |
|
17bfd5dbc0f1
Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents:
27487
diff
changeset
|
4417 long_getnewargs(PyLongObject *v) |
|
17bfd5dbc0f1
Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents:
27487
diff
changeset
|
4418 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4419 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
|
4420 } |
|
17bfd5dbc0f1
Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents:
27487
diff
changeset
|
4421 |
|
42417
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4422 static PyObject * |
|
53676
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4423 long_get0(PyLongObject *v, void *context) { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4424 return PyLong_FromLong(0L); |
|
53676
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4425 } |
|
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4426 |
|
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4427 static PyObject * |
|
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4428 long_get1(PyLongObject *v, void *context) { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4429 return PyLong_FromLong(1L); |
|
42417
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4430 } |
|
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4431 |
|
42753
077fe7860cc9
Finish the work on __round__ and __trunc__.
Guido van Rossum <guido@python.org>
parents:
42719
diff
changeset
|
4432 static PyObject * |
|
42817
5355337709e1
Implementation of PEP 3101, Advanced String Formatting.
Eric Smith <eric@trueblade.com>
parents:
42753
diff
changeset
|
4433 long__format__(PyObject *self, PyObject *args) |
|
5355337709e1
Implementation of PEP 3101, Advanced String Formatting.
Eric Smith <eric@trueblade.com>
parents:
42753
diff
changeset
|
4434 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4435 PyObject *format_spec; |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4436 _PyUnicodeWriter writer; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4437 int ret; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4438 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4439 if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4440 return NULL; |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4441 |
|
83433
edf029fc9591
Close #17694: Add minimum length to _PyUnicodeWriter
Victor Stinner <victor.stinner@gmail.com>
parents:
82112
diff
changeset
|
4442 _PyUnicodeWriter_Init(&writer); |
|
77223
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4443 ret = _PyLong_FormatAdvancedWriter( |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4444 &writer, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4445 self, |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4446 format_spec, 0, PyUnicode_GET_LENGTH(format_spec)); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4447 if (ret == -1) { |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4448 _PyUnicodeWriter_Dealloc(&writer); |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4449 return NULL; |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4450 } |
|
22b56b0b8619
Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args and str.format(args)
Victor Stinner <victor.stinner@gmail.com>
parents:
76560
diff
changeset
|
4451 return _PyUnicodeWriter_Finish(&writer); |
|
42817
5355337709e1
Implementation of PEP 3101, Advanced String Formatting.
Eric Smith <eric@trueblade.com>
parents:
42753
diff
changeset
|
4452 } |
|
5355337709e1
Implementation of PEP 3101, Advanced String Formatting.
Eric Smith <eric@trueblade.com>
parents:
42753
diff
changeset
|
4453 |
|
61924
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4454 /* Return a pair (q, r) such that a = b * q + r, and |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4455 abs(r) <= abs(b)/2, with equality possible only if q is even. |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4456 In other words, q == a / b, rounded to the nearest integer using |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4457 round-half-to-even. */ |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4458 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4459 PyObject * |
|
62154
0d9347934cc5
Fix naming inconsistency.
Mark Dickinson <dickinsm@gmail.com>
parents:
61940
diff
changeset
|
4460 _PyLong_DivmodNear(PyObject *a, PyObject *b) |
|
61924
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4461 { |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4462 PyLongObject *quo = NULL, *rem = NULL; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4463 PyObject *one = NULL, *twice_rem, *result, *temp; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4464 int cmp, quo_is_odd, quo_is_neg; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4465 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4466 /* Equivalent Python code: |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4467 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4468 def divmod_near(a, b): |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4469 q, r = divmod(a, b) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4470 # round up if either r / b > 0.5, or r / b == 0.5 and q is odd. |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4471 # The expression r / b > 0.5 is equivalent to 2 * r > b if b is |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4472 # positive, 2 * r < b if b negative. |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4473 greater_than_half = 2*r > b if b > 0 else 2*r < b |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4474 exactly_half = 2*r == b |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4475 if greater_than_half or exactly_half and q % 2 == 1: |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4476 q += 1 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4477 r -= b |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4478 return q, r |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4479 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4480 */ |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4481 if (!PyLong_Check(a) || !PyLong_Check(b)) { |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4482 PyErr_SetString(PyExc_TypeError, |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4483 "non-integer arguments in division"); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4484 return NULL; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4485 } |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4486 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4487 /* Do a and b have different signs? If so, quotient is negative. */ |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4488 quo_is_neg = (Py_SIZE(a) < 0) != (Py_SIZE(b) < 0); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4489 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4490 one = PyLong_FromLong(1L); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4491 if (one == NULL) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4492 return NULL; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4493 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4494 if (long_divrem((PyLongObject*)a, (PyLongObject*)b, &quo, &rem) < 0) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4495 goto error; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4496 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4497 /* compare twice the remainder with the divisor, to see |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4498 if we need to adjust the quotient and remainder */ |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4499 twice_rem = long_lshift((PyObject *)rem, one); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4500 if (twice_rem == NULL) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4501 goto error; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4502 if (quo_is_neg) { |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4503 temp = long_neg((PyLongObject*)twice_rem); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4504 Py_DECREF(twice_rem); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4505 twice_rem = temp; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4506 if (twice_rem == NULL) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4507 goto error; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4508 } |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4509 cmp = long_compare((PyLongObject *)twice_rem, (PyLongObject *)b); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4510 Py_DECREF(twice_rem); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4511 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4512 quo_is_odd = Py_SIZE(quo) != 0 && ((quo->ob_digit[0] & 1) != 0); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4513 if ((Py_SIZE(b) < 0 ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) { |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4514 /* fix up quotient */ |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4515 if (quo_is_neg) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4516 temp = long_sub(quo, (PyLongObject *)one); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4517 else |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4518 temp = long_add(quo, (PyLongObject *)one); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4519 Py_DECREF(quo); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4520 quo = (PyLongObject *)temp; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4521 if (quo == NULL) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4522 goto error; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4523 /* and remainder */ |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4524 if (quo_is_neg) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4525 temp = long_add(rem, (PyLongObject *)b); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4526 else |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4527 temp = long_sub(rem, (PyLongObject *)b); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4528 Py_DECREF(rem); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4529 rem = (PyLongObject *)temp; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4530 if (rem == NULL) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4531 goto error; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4532 } |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4533 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4534 result = PyTuple_New(2); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4535 if (result == NULL) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4536 goto error; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4537 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4538 /* PyTuple_SET_ITEM steals references */ |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4539 PyTuple_SET_ITEM(result, 0, (PyObject *)quo); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4540 PyTuple_SET_ITEM(result, 1, (PyObject *)rem); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4541 Py_DECREF(one); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4542 return result; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4543 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4544 error: |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4545 Py_XDECREF(quo); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4546 Py_XDECREF(rem); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4547 Py_XDECREF(one); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4548 return NULL; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4549 } |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4550 |
|
42817
5355337709e1
Implementation of PEP 3101, Advanced String Formatting.
Eric Smith <eric@trueblade.com>
parents:
42753
diff
changeset
|
4551 static PyObject * |
|
42753
077fe7860cc9
Finish the work on __round__ and __trunc__.
Guido van Rossum <guido@python.org>
parents:
42719
diff
changeset
|
4552 long_round(PyObject *self, PyObject *args) |
|
077fe7860cc9
Finish the work on __round__ and __trunc__.
Guido van Rossum <guido@python.org>
parents:
42719
diff
changeset
|
4553 { |
|
61924
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4554 PyObject *o_ndigits=NULL, *temp, *result, *ndigits; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4555 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4556 /* To round an integer m to the nearest 10**n (n positive), we make use of |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4557 * the divmod_near operation, defined by: |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4558 * |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4559 * divmod_near(a, b) = (q, r) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4560 * |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4561 * where q is the nearest integer to the quotient a / b (the |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4562 * nearest even integer in the case of a tie) and r == a - q * b. |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4563 * Hence q * b = a - r is the nearest multiple of b to a, |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4564 * preferring even multiples in the case of a tie. |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4565 * |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4566 * So the nearest multiple of 10**n to m is: |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4567 * |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4568 * m - divmod_near(m, 10**n)[1]. |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4569 */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4570 if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4571 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4572 if (o_ndigits == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4573 return long_long(self); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4574 |
|
61924
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4575 ndigits = PyNumber_Index(o_ndigits); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4576 if (ndigits == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4577 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4578 |
|
61924
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4579 /* if ndigits >= 0 then no rounding is necessary; return self unchanged */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4580 if (Py_SIZE(ndigits) >= 0) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4581 Py_DECREF(ndigits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4582 return long_long(self); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4583 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4584 |
|
61924
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4585 /* result = self - divmod_near(self, 10 ** -ndigits)[1] */ |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4586 temp = long_neg((PyLongObject*)ndigits); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4587 Py_DECREF(ndigits); |
|
61924
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4588 ndigits = temp; |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4589 if (ndigits == NULL) |
|
61924
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4590 return NULL; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4591 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4592 result = PyLong_FromLong(10L); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4593 if (result == NULL) { |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4594 Py_DECREF(ndigits); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4595 return NULL; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4596 } |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4597 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4598 temp = long_pow(result, ndigits, Py_None); |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4599 Py_DECREF(ndigits); |
|
61924
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4600 Py_DECREF(result); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4601 result = temp; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4602 if (result == NULL) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4603 return NULL; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4604 |
|
62154
0d9347934cc5
Fix naming inconsistency.
Mark Dickinson <dickinsm@gmail.com>
parents:
61940
diff
changeset
|
4605 temp = _PyLong_DivmodNear(self, result); |
|
61924
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4606 Py_DECREF(result); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4607 result = temp; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4608 if (result == NULL) |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4609 return NULL; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4610 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4611 temp = long_sub((PyLongObject *)self, |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4612 (PyLongObject *)PyTuple_GET_ITEM(result, 1)); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4613 Py_DECREF(result); |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4614 result = temp; |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4615 |
|
81a580d947ef
Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near
Mark Dickinson <dickinsm@gmail.com>
parents:
61873
diff
changeset
|
4616 return result; |
|
42753
077fe7860cc9
Finish the work on __round__ and __trunc__.
Guido van Rossum <guido@python.org>
parents:
42719
diff
changeset
|
4617 } |
|
077fe7860cc9
Finish the work on __round__ and __trunc__.
Guido van Rossum <guido@python.org>
parents:
42719
diff
changeset
|
4618 |
|
47466
58f4b60773fe
Merged revisions 63856-63857,63859-63860 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
47393
diff
changeset
|
4619 static PyObject * |
|
58f4b60773fe
Merged revisions 63856-63857,63859-63860 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
47393
diff
changeset
|
4620 long_sizeof(PyLongObject *v) |
|
58f4b60773fe
Merged revisions 63856-63857,63859-63860 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
47393
diff
changeset
|
4621 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4622 Py_ssize_t res; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4623 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4624 res = offsetof(PyLongObject, ob_digit) + ABS(Py_SIZE(v))*sizeof(digit); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4625 return PyLong_FromSsize_t(res); |
|
47466
58f4b60773fe
Merged revisions 63856-63857,63859-63860 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
47393
diff
changeset
|
4626 } |
|
58f4b60773fe
Merged revisions 63856-63857,63859-63860 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
47393
diff
changeset
|
4627 |
|
50207
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4628 static PyObject * |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4629 long_bit_length(PyLongObject *v) |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4630 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4631 PyLongObject *result, *x, *y; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4632 Py_ssize_t ndigits, msd_bits = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4633 digit msd; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4634 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4635 assert(v != NULL); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4636 assert(PyLong_Check(v)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4637 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4638 ndigits = ABS(Py_SIZE(v)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4639 if (ndigits == 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4640 return PyLong_FromLong(0); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4641 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4642 msd = v->ob_digit[ndigits-1]; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4643 while (msd >= 32) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4644 msd_bits += 6; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4645 msd >>= 6; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4646 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4647 msd_bits += (long)(BitLengthTable[msd]); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4648 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4649 if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4650 return PyLong_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4651 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4652 /* expression above may overflow; use Python integers instead */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4653 result = (PyLongObject *)PyLong_FromSsize_t(ndigits - 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4654 if (result == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4655 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4656 x = (PyLongObject *)PyLong_FromLong(PyLong_SHIFT); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4657 if (x == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4658 goto error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4659 y = (PyLongObject *)long_mul(result, x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4660 Py_DECREF(x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4661 if (y == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4662 goto error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4663 Py_DECREF(result); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4664 result = y; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4665 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4666 x = (PyLongObject *)PyLong_FromLong((long)msd_bits); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4667 if (x == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4668 goto error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4669 y = (PyLongObject *)long_add(result, x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4670 Py_DECREF(x); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4671 if (y == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4672 goto error; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4673 Py_DECREF(result); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4674 result = y; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4675 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4676 return (PyObject *)result; |
|
50207
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4677 |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4678 error: |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4679 Py_DECREF(result); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4680 return NULL; |
|
50207
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4681 } |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4682 |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4683 PyDoc_STRVAR(long_bit_length_doc, |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4684 "int.bit_length() -> int\n\ |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4685 \n\ |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4686 Number of bits necessary to represent self in binary.\n\ |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4687 >>> bin(37)\n\ |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4688 '0b100101'\n\ |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4689 >>> (37).bit_length()\n\ |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4690 6"); |
|
92e21652f2f4
Forward merge of r67822 to py3k: add bit_length method to int.
Mark Dickinson <dickinsm@gmail.com>
parents:
50026
diff
changeset
|
4691 |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
46460
diff
changeset
|
4692 #if 0 |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
46460
diff
changeset
|
4693 static PyObject * |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
46460
diff
changeset
|
4694 long_is_finite(PyObject *v) |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
46460
diff
changeset
|
4695 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4696 Py_RETURN_TRUE; |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
46460
diff
changeset
|
4697 } |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
46460
diff
changeset
|
4698 #endif |
|
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
46460
diff
changeset
|
4699 |
|
58223
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4700 |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4701 static PyObject * |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4702 long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds) |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4703 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4704 PyObject *byteorder_str; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4705 PyObject *is_signed_obj = NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4706 Py_ssize_t length; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4707 int little_endian; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4708 int is_signed; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4709 PyObject *bytes; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4710 static char *kwlist[] = {"length", "byteorder", "signed", NULL}; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4711 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4712 if (!PyArg_ParseTupleAndKeywords(args, kwds, "nU|O:to_bytes", kwlist, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4713 &length, &byteorder_str, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4714 &is_signed_obj)) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4715 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4716 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4717 if (args != NULL && Py_SIZE(args) > 2) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4718 PyErr_SetString(PyExc_TypeError, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4719 "'signed' is a keyword-only argument"); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4720 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4721 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4722 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4723 if (!PyUnicode_CompareWithASCIIString(byteorder_str, "little")) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4724 little_endian = 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4725 else if (!PyUnicode_CompareWithASCIIString(byteorder_str, "big")) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4726 little_endian = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4727 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4728 PyErr_SetString(PyExc_ValueError, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4729 "byteorder must be either 'little' or 'big'"); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4730 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4731 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4732 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4733 if (is_signed_obj != NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4734 int cmp = PyObject_IsTrue(is_signed_obj); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4735 if (cmp < 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4736 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4737 is_signed = cmp ? 1 : 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4738 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4739 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4740 /* If the signed argument was omitted, use False as the |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4741 default. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4742 is_signed = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4743 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4744 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4745 if (length < 0) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4746 PyErr_SetString(PyExc_ValueError, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4747 "length argument must be non-negative"); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4748 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4749 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4750 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4751 bytes = PyBytes_FromStringAndSize(NULL, length); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4752 if (bytes == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4753 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4754 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4755 if (_PyLong_AsByteArray(v, (unsigned char *)PyBytes_AS_STRING(bytes), |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4756 length, little_endian, is_signed) < 0) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4757 Py_DECREF(bytes); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4758 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4759 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4760 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4761 return bytes; |
|
58223
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4762 } |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4763 |
|
58596
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4764 PyDoc_STRVAR(long_to_bytes_doc, |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4765 "int.to_bytes(length, byteorder, *, signed=False) -> bytes\n\ |
|
58223
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4766 \n\ |
|
58596
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4767 Return an array of bytes representing an integer.\n\ |
|
58223
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4768 \n\ |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4769 The integer is represented using length bytes. An OverflowError is\n\ |
|
58596
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4770 raised if the integer is not representable with the given number of\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4771 bytes.\n\ |
|
58223
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4772 \n\ |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4773 The byteorder argument determines the byte order used to represent the\n\ |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4774 integer. If byteorder is 'big', the most significant byte is at the\n\ |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4775 beginning of the byte array. If byteorder is 'little', the most\n\ |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4776 significant byte is at the end of the byte array. To request the native\n\ |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4777 byte order of the host system, use `sys.byteorder' as the byte order value.\n\ |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4778 \n\ |
|
58596
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4779 The signed keyword-only argument determines whether two's complement is\n\ |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4780 used to represent the integer. If signed is False and a negative integer\n\ |
|
58596
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4781 is given, an OverflowError is raised."); |
|
58223
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4782 |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4783 static PyObject * |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4784 long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds) |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4785 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4786 PyObject *byteorder_str; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4787 PyObject *is_signed_obj = NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4788 int little_endian; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4789 int is_signed; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4790 PyObject *obj; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4791 PyObject *bytes; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4792 PyObject *long_obj; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4793 static char *kwlist[] = {"bytes", "byteorder", "signed", NULL}; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4794 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4795 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OU|O:from_bytes", kwlist, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4796 &obj, &byteorder_str, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4797 &is_signed_obj)) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4798 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4799 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4800 if (args != NULL && Py_SIZE(args) > 2) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4801 PyErr_SetString(PyExc_TypeError, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4802 "'signed' is a keyword-only argument"); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4803 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4804 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4805 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4806 if (!PyUnicode_CompareWithASCIIString(byteorder_str, "little")) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4807 little_endian = 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4808 else if (!PyUnicode_CompareWithASCIIString(byteorder_str, "big")) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4809 little_endian = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4810 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4811 PyErr_SetString(PyExc_ValueError, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4812 "byteorder must be either 'little' or 'big'"); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4813 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4814 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4815 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4816 if (is_signed_obj != NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4817 int cmp = PyObject_IsTrue(is_signed_obj); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4818 if (cmp < 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4819 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4820 is_signed = cmp ? 1 : 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4821 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4822 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4823 /* If the signed argument was omitted, use False as the |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4824 default. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4825 is_signed = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4826 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4827 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4828 bytes = PyObject_Bytes(obj); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4829 if (bytes == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4830 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4831 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4832 long_obj = _PyLong_FromByteArray( |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4833 (unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes), |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4834 little_endian, is_signed); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4835 Py_DECREF(bytes); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4836 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4837 /* If from_bytes() was used on subclass, allocate new subclass |
|
85418
4d62a62ba44d
Issue #18783: Removed existing mentions of Python long type in docstrings,
Serhiy Storchaka <storchaka@gmail.com>
parents:
84995
diff
changeset
|
4838 * instance, initialize it with decoded int value and return it. |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4839 */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4840 if (type != &PyLong_Type && PyType_IsSubtype(type, &PyLong_Type)) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4841 PyLongObject *newobj; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4842 int i; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4843 Py_ssize_t n = ABS(Py_SIZE(long_obj)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4844 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4845 newobj = (PyLongObject *)type->tp_alloc(type, n); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4846 if (newobj == NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4847 Py_DECREF(long_obj); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4848 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4849 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4850 assert(PyLong_Check(newobj)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4851 Py_SIZE(newobj) = Py_SIZE(long_obj); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4852 for (i = 0; i < n; i++) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4853 newobj->ob_digit[i] = |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4854 ((PyLongObject *)long_obj)->ob_digit[i]; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4855 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4856 Py_DECREF(long_obj); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4857 return (PyObject *)newobj; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4858 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4859 |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4860 return long_obj; |
|
58223
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4861 } |
|
f9c0c411f80c
Issue #1023290: Added API for the conversion of longs to bytes and vice-versa.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
58088
diff
changeset
|
4862 |
|
58596
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4863 PyDoc_STRVAR(long_from_bytes_doc, |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4864 "int.from_bytes(bytes, byteorder, *, signed=False) -> int\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4865 \n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4866 Return the integer represented by the given array of bytes.\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4867 \n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4868 The bytes argument must either support the buffer protocol or be an\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4869 iterable object producing bytes. Bytes and bytearray are examples of\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4870 built-in objects that support the buffer protocol.\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4871 \n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4872 The byteorder argument determines the byte order used to represent the\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4873 integer. If byteorder is 'big', the most significant byte is at the\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4874 beginning of the byte array. If byteorder is 'little', the most\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4875 significant byte is at the end of the byte array. To request the native\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4876 byte order of the host system, use `sys.byteorder' as the byte order value.\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4877 \n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4878 The signed keyword-only argument indicates whether two's complement is\n\ |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4879 used to represent the integer."); |
|
5a7d7eeb88c1
Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions.
Mark Dickinson <dickinsm@gmail.com>
parents:
58582
diff
changeset
|
4880 |
|
27521
17bfd5dbc0f1
Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents:
27487
diff
changeset
|
4881 static PyMethodDef long_methods[] = { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4882 {"conjugate", (PyCFunction)long_long, METH_NOARGS, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4883 "Returns self, the complex conjugate of any int."}, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4884 {"bit_length", (PyCFunction)long_bit_length, METH_NOARGS, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4885 long_bit_length_doc}, |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
46460
diff
changeset
|
4886 #if 0 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4887 {"is_finite", (PyCFunction)long_is_finite, METH_NOARGS, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4888 "Returns always True."}, |
|
46477
b69f443ef480
Merged revisions 62380,62382-62383 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents:
46460
diff
changeset
|
4889 #endif |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4890 {"to_bytes", (PyCFunction)long_to_bytes, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4891 METH_VARARGS|METH_KEYWORDS, long_to_bytes_doc}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4892 {"from_bytes", (PyCFunction)long_from_bytes, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4893 METH_VARARGS|METH_KEYWORDS|METH_CLASS, long_from_bytes_doc}, |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4894 {"__trunc__", (PyCFunction)long_long, METH_NOARGS, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4895 "Truncating an Integral returns itself."}, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4896 {"__floor__", (PyCFunction)long_long, METH_NOARGS, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4897 "Flooring an Integral returns itself."}, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4898 {"__ceil__", (PyCFunction)long_long, METH_NOARGS, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4899 "Ceiling of an Integral returns itself."}, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4900 {"__round__", (PyCFunction)long_round, METH_VARARGS, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4901 "Rounding an Integral returns itself.\n" |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4902 "Rounding with an ndigits argument also returns an integer."}, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4903 {"__getnewargs__", (PyCFunction)long_getnewargs, METH_NOARGS}, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4904 {"__format__", (PyCFunction)long__format__, METH_VARARGS}, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4905 {"__sizeof__", (PyCFunction)long_sizeof, METH_NOARGS, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4906 "Returns size in memory, in bytes"}, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4907 {NULL, NULL} /* sentinel */ |
|
27521
17bfd5dbc0f1
Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents:
27487
diff
changeset
|
4908 }; |
|
17bfd5dbc0f1
Implement appropriate __getnewargs__ for all immutable subclassable builtin
Guido van Rossum <guido@python.org>
parents:
27487
diff
changeset
|
4909 |
|
42417
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4910 static PyGetSetDef long_getset[] = { |
|
53676
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4911 {"real", |
|
42417
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4912 (getter)long_long, (setter)NULL, |
|
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4913 "the real part of a complex number", |
|
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4914 NULL}, |
|
53676
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4915 {"imag", |
|
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4916 (getter)long_get0, (setter)NULL, |
|
42417
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4917 "the imaginary part of a complex number", |
|
53676
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4918 NULL}, |
|
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4919 {"numerator", |
|
42417
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4920 (getter)long_long, (setter)NULL, |
|
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4921 "the numerator of a rational number in lowest terms", |
|
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4922 NULL}, |
|
53676
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4923 {"denominator", |
|
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4924 (getter)long_get1, (setter)NULL, |
|
42417
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4925 "the denominator of a rational number in lowest terms", |
|
53676
903e80f3e811
Merged revisions 72202 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
53541
diff
changeset
|
4926 NULL}, |
|
42417
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4927 {NULL} /* Sentinel */ |
|
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4928 }; |
|
d3a5c796c8ba
Changes to long and float by Jeffrey Jasskin to conform to PEP 3141.
Guido van Rossum <guido@python.org>
parents:
42334
diff
changeset
|
4929 |
|
23832
ed1ba37a46b7
Patch #568124: Add doc string macros.
Martin v. Löwis <martin@v.loewis.de>
parents:
23248
diff
changeset
|
4930 PyDoc_STRVAR(long_doc, |
|
79587
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4931 "int(x=0) -> integer\n\ |
|
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4932 int(x, base=10) -> integer\n\ |
|
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4933 \n\ |
|
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4934 Convert a number or string to an integer, or return 0 if no arguments\n\ |
|
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4935 are given. If x is a number, return x.__int__(). For floating point\n\ |
|
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4936 numbers, this truncates towards zero.\n\ |
|
18933
09df3254b49d
Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents:
18607
diff
changeset
|
4937 \n\ |
|
79587
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4938 If x is not a number or if base is given, then x must be a string,\n\ |
|
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4939 bytes, or bytearray instance representing an integer literal in the\n\ |
|
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4940 given base. The literal can be preceded by '+' or '-' and be surrounded\n\ |
|
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4941 by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.\n\ |
|
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4942 Base 0 means to interpret the base from the string as an integer literal.\n\ |
|
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4943 >>> int('0b100', base=0)\n\ |
|
e4598364ea29
Issue #14783: Improve int() docstring and also str(), range(), and slice().
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
79069
diff
changeset
|
4944 4"); |
|
18933
09df3254b49d
Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents:
18607
diff
changeset
|
4945 |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4946 static PyNumberMethods long_as_number = { |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4947 (binaryfunc)long_add, /*nb_add*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4948 (binaryfunc)long_sub, /*nb_subtract*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4949 (binaryfunc)long_mul, /*nb_multiply*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4950 long_mod, /*nb_remainder*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4951 long_divmod, /*nb_divmod*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4952 long_pow, /*nb_power*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4953 (unaryfunc)long_neg, /*nb_negative*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4954 (unaryfunc)long_long, /*tp_positive*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4955 (unaryfunc)long_abs, /*tp_absolute*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4956 (inquiry)long_bool, /*tp_bool*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4957 (unaryfunc)long_invert, /*nb_invert*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4958 long_lshift, /*nb_lshift*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4959 (binaryfunc)long_rshift, /*nb_rshift*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4960 long_and, /*nb_and*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4961 long_xor, /*nb_xor*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4962 long_or, /*nb_or*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4963 long_long, /*nb_int*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4964 0, /*nb_reserved*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4965 long_float, /*nb_float*/ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4966 0, /* nb_inplace_add */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4967 0, /* nb_inplace_subtract */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4968 0, /* nb_inplace_multiply */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4969 0, /* nb_inplace_remainder */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4970 0, /* nb_inplace_power */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4971 0, /* nb_inplace_lshift */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4972 0, /* nb_inplace_rshift */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4973 0, /* nb_inplace_and */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4974 0, /* nb_inplace_xor */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4975 0, /* nb_inplace_or */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4976 long_div, /* nb_floor_divide */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4977 long_true_divide, /* nb_true_divide */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4978 0, /* nb_inplace_floor_divide */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4979 0, /* nb_inplace_true_divide */ |
|
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
4980 long_long, /* nb_index */ |
| 230 | 4981 }; |
| 4982 | |
|
5396
d1447950fa04
Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents:
5288
diff
changeset
|
4983 PyTypeObject PyLong_Type = { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4984 PyVarObject_HEAD_INIT(&PyType_Type, 0) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4985 "int", /* tp_name */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4986 offsetof(PyLongObject, ob_digit), /* tp_basicsize */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4987 sizeof(digit), /* tp_itemsize */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4988 long_dealloc, /* tp_dealloc */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4989 0, /* tp_print */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4990 0, /* tp_getattr */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4991 0, /* tp_setattr */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4992 0, /* tp_reserved */ |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4993 long_to_decimal_string, /* tp_repr */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4994 &long_as_number, /* tp_as_number */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4995 0, /* tp_as_sequence */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4996 0, /* tp_as_mapping */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4997 (hashfunc)long_hash, /* tp_hash */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
4998 0, /* tp_call */ |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
61397
diff
changeset
|
4999 long_to_decimal_string, /* tp_str */ |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5000 PyObject_GenericGetAttr, /* tp_getattro */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5001 0, /* tp_setattro */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5002 0, /* tp_as_buffer */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5003 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5004 Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5005 long_doc, /* tp_doc */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5006 0, /* tp_traverse */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5007 0, /* tp_clear */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5008 long_richcompare, /* tp_richcompare */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5009 0, /* tp_weaklistoffset */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5010 0, /* tp_iter */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5011 0, /* tp_iternext */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5012 long_methods, /* tp_methods */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5013 0, /* tp_members */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5014 long_getset, /* tp_getset */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5015 0, /* tp_base */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5016 0, /* tp_dict */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5017 0, /* tp_descr_get */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5018 0, /* tp_descr_set */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5019 0, /* tp_dictoffset */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5020 0, /* tp_init */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5021 0, /* tp_alloc */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5022 long_new, /* tp_new */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5023 PyObject_Del, /* tp_free */ |
| 230 | 5024 }; |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5025 |
|
52215
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5026 static PyTypeObject Int_InfoType; |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5027 |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5028 PyDoc_STRVAR(int_info__doc__, |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5029 "sys.int_info\n\ |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5030 \n\ |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5031 A struct sequence that holds information about Python's\n\ |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5032 internal representation of integers. The attributes are read only."); |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5033 |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5034 static PyStructSequence_Field int_info_fields[] = { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5035 {"bits_per_digit", "size of a digit in bits"}, |
|
61491
829a86e11bd7
Merged revisions 81036 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
61466
diff
changeset
|
5036 {"sizeof_digit", "size in bytes of the C type used to represent a digit"}, |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5037 {NULL, NULL} |
|
52215
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5038 }; |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5039 |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5040 static PyStructSequence_Desc int_info_desc = { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5041 "sys.int_info", /* name */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5042 int_info__doc__, /* doc */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5043 int_info_fields, /* fields */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5044 2 /* number of fields */ |
|
52215
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5045 }; |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5046 |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5047 PyObject * |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5048 PyLong_GetInfo(void) |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5049 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5050 PyObject* int_info; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5051 int field = 0; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5052 int_info = PyStructSequence_New(&Int_InfoType); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5053 if (int_info == NULL) |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5054 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5055 PyStructSequence_SET_ITEM(int_info, field++, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5056 PyLong_FromLong(PyLong_SHIFT)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5057 PyStructSequence_SET_ITEM(int_info, field++, |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5058 PyLong_FromLong(sizeof(digit))); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5059 if (PyErr_Occurred()) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5060 Py_CLEAR(int_info); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5061 return NULL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5062 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5063 return int_info; |
|
52215
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5064 } |
|
bb5de24a343f
Issue #4258: Make it possible to use 30-bit digits for PyLongs:
Mark Dickinson <dickinsm@gmail.com>
parents:
51855
diff
changeset
|
5065 |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5066 int |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5067 _PyLong_Init(void) |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5068 { |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5069 #if NSMALLNEGINTS + NSMALLPOSINTS > 0 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5070 int ival, size; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5071 PyLongObject *v = small_ints; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5072 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5073 for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5074 size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5075 if (Py_TYPE(v) == &PyLong_Type) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5076 /* The element is already initialized, most likely |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5077 * the Python interpreter was initialized before. |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5078 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5079 Py_ssize_t refcnt; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5080 PyObject* op = (PyObject*)v; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5081 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5082 refcnt = Py_REFCNT(op) < 0 ? 0 : Py_REFCNT(op); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5083 _Py_NewReference(op); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5084 /* _Py_NewReference sets the ref count to 1 but |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5085 * the ref count might be larger. Set the refcnt |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5086 * to the original refcnt + 1 */ |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5087 Py_REFCNT(op) = refcnt + 1; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5088 assert(Py_SIZE(op) == size); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5089 assert(v->ob_digit[0] == abs(ival)); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5090 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5091 else { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5092 PyObject_INIT(v, &PyLong_Type); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5093 } |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5094 Py_SIZE(v) = size; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5095 v->ob_digit[0] = abs(ival); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5096 } |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5097 #endif |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5098 /* initialize int_info */ |
|
84793
fc718c177ee6
Issue #18520: Add a new PyStructSequence_InitType2() function, same than
Victor Stinner <victor.stinner@gmail.com>
parents:
84699
diff
changeset
|
5099 if (Int_InfoType.tp_name == NULL) { |
|
fc718c177ee6
Issue #18520: Add a new PyStructSequence_InitType2() function, same than
Victor Stinner <victor.stinner@gmail.com>
parents:
84699
diff
changeset
|
5100 if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) |
|
fc718c177ee6
Issue #18520: Add a new PyStructSequence_InitType2() function, same than
Victor Stinner <victor.stinner@gmail.com>
parents:
84699
diff
changeset
|
5101 return 0; |
|
fc718c177ee6
Issue #18520: Add a new PyStructSequence_InitType2() function, same than
Victor Stinner <victor.stinner@gmail.com>
parents:
84699
diff
changeset
|
5102 } |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5103 |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5104 return 1; |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5105 } |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5106 |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5107 void |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5108 PyLong_Fini(void) |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5109 { |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5110 /* Integers are currently statically allocated. Py_DECREF is not |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5111 needed, but Python must forget about the reference or multiple |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5112 reinitializations will fail. */ |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5113 #if NSMALLNEGINTS + NSMALLPOSINTS > 0 |
|
61467
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5114 int i; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5115 PyLongObject *v = small_ints; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5116 for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) { |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5117 _Py_DEC_REFTOTAL; |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5118 _Py_ForgetReference((PyObject*)v); |
|
f197407bdba2
Recorded merge of revisions 81032 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
60446
diff
changeset
|
5119 } |
|
40626
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5120 #endif |
|
4aee3f672f77
Merged the int/long unification branch, by very crude means (sorry Thomas!).
Guido van Rossum <guido@python.org>
parents:
40450
diff
changeset
|
5121 } |
