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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1 /* Long (arbitrary precision) integer object implementation */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2
242
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
3 /* XXX The functional organization of this file is terrible */
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
4
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
5 #include "Python.h"
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
6 #include "longintrepr.h"
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
109 Doesn't attempt to free the storage--in most cases, due to the nature
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
110 of the algorithms used, this could save at most be one word anyway. */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
123 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
126 Return NULL and set exception if we run out of memory. */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
152 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
244 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
338
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
424 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
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
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
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
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
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
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
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
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
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
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
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
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
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
6ea366a2b2a6 longobject.c:
Tim Peters <tim.peters@gmail.com>
parents: 18091
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1527 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1553 (as function result) and the remainder (through *prem).
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1554 The sign of a is ignored; n should not be zero. */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1568 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1909 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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>
parents: 84983 84995
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>
parents: 84983 84995
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
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2324 PyObject *v, *unicode = PyUnicode_FromUnicode(u, length);
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2325 if (unicode == NULL)
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2326 return NULL;
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2327 v = PyLong_FromUnicodeObject(unicode, base);
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2328 Py_DECREF(unicode);
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2329 return v;
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2330 }
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2331
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2332 PyObject *
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2333 PyLong_FromUnicodeObject(PyObject *u, int base)
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2334 {
84996
4fd48a807812 Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents: 84983 84995
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
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2337 Py_ssize_t buflen;
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
2338
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
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
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
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>
parents: 84983 84995
diff changeset
2357 PyErr_Format(PyExc_ValueError,
4fd48a807812 Issue #16741: Fix an error reporting in int().
Serhiy Storchaka <storchaka@gmail.com>
parents: 84983 84995
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>
parents: 84983 84995
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2361 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2369
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2430 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2557 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2709 /* Methods */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2710
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2715 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2716
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2738 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2871 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2872
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2873 /* Subtract the absolute values of two integers. */
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2929 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2930
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
2931 static PyObject *
43313
d1552c150e91 Drop convert_binop.
Martin v. Löwis <martin@v.loewis.de>
parents: 43137
diff changeset
2932 long_add(PyLongObject *a, PyLongObject *b)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2959 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2960
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
2961 static PyObject *
43313
d1552c150e91 Drop convert_binop.
Martin v. Löwis <martin@v.loewis.de>
parents: 43137
diff changeset
2962 long_sub(PyLongObject *a, PyLongObject *b)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2988 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
d1552c150e91 Drop convert_binop.
Martin v. Löwis <martin@v.loewis.de>
parents: 43137
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3424 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3425
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3426 /* The / and % operators are now defined in terms of divmod().
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3427 The expression a mod b has the value a - b*floor(a/b).
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3428 The long_divrem function gives the remainder after division of
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3429 |a| by |b|, with the sign of a. This is also expressed
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3430 as a - b*trunc(a/b), if trunc truncates towards zero.
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3437 So, to get from rem to mod, we have to add b if a and b
242
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
3438 have different signs. We then subtract one from the 'div'
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
3439 part of the outcome to keep the invariant intact. */
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
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
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
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
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3489 }
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3490
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3491 static PyObject *
43313
d1552c150e91 Drop convert_binop.
Martin v. Löwis <martin@v.loewis.de>
parents: 43137
diff changeset
3492 long_div(PyObject *a, PyObject *b)
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
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
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3500 }
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
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
d1552c150e91 Drop convert_binop.
Martin v. Löwis <martin@v.loewis.de>
parents: 43137
diff changeset
3766 long_mod(PyObject *a, PyObject *b)
613
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
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
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3775 }
405a2fec7454 Add prototypes.
Guido van Rossum <guido@python.org>
parents: 590
diff changeset
3776
5396
d1447950fa04 Quickly renamed the last directory.
Guido van Rossum <guido@python.org>
parents: 5288
diff changeset
3777 static PyObject *
43313
d1552c150e91 Drop convert_binop.
Martin v. Löwis <martin@v.loewis.de>
parents: 43137
diff changeset
3778 long_divmod(PyObject *a, PyObject *b)
230
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3798 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3989 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4008 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4029 }
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4030
242
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
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
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
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
d1552c150e91 Drop convert_binop.
Martin v. Löwis <martin@v.loewis.de>
parents: 43137
diff changeset
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
d1552c150e91 Drop convert_binop.
Martin v. Löwis <martin@v.loewis.de>
parents: 43137
diff changeset
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
d1552c150e91 Drop convert_binop.
Martin v. Löwis <martin@v.loewis.de>
parents: 43137
diff changeset
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
d1552c150e91 Drop convert_binop.
Martin v. Löwis <martin@v.loewis.de>
parents: 43137
diff changeset
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
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
4310 }
316a0d9c0096 Many small changes
Guido van Rossum <guido@python.org>
parents: 230
diff changeset
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
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72345
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4981 };
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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
7ba9612058a4 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
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 }