python-gmp 0.6.0a0__tar.gz → 0.6.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.readthedocs.yaml +1 -1
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/PKG-INFO +2 -2
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/README.rst +1 -1
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/bench/collatz.py +12 -1
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/bench/mul.py +2 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/gmp.c +237 -270
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/scripts/cibw_before_all.sh +1 -1
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/tests/conftest.py +1 -1
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/tests/test_mpz.py +16 -9
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.backportrc.json +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.clang-format +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.github/dependabot.yml +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.github/workflows/backport.yml +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.github/workflows/ci.yml +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.github/workflows/coverage.yml +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.github/workflows/linter.yml +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.github/workflows/publish.yml +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.github/workflows/wheels.yml +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.gitignore +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/.pre-commit-config.yaml +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/LICENSE +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/bench/README.rst +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/docs/conf.py +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/docs/index.rst +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/fmt.c +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/meson.build +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/mpz.h +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/pyproject.toml +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/pythoncapi_compat.h +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/scripts/dll-importexport.diff +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/scripts/fat_build_fix.diff +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/scripts/gcc15.diff +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/scripts/gitversion.py +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/tests/test_functions.py +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/tests/utils.py +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/utils.c +0 -0
- {python_gmp-0.6.0a0 → python_gmp-0.6.0a1}/utils.h +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-gmp
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.0a1
|
|
4
4
|
Summary: Safe bindings to the GNU GMP library
|
|
5
5
|
Keywords: gmp,multiple-precision,arbitrary-precision,bignum
|
|
6
6
|
Author-Email: Sergey B Kirpichev <skirpichev@gmail.com>
|
|
@@ -53,7 +53,7 @@ Python-GMP
|
|
|
53
53
|
==========
|
|
54
54
|
|
|
55
55
|
Python extension module, providing bindings to the GNU GMP via the `ZZ library
|
|
56
|
-
<https://github.com/diofant/zz>`_ (version 0.
|
|
56
|
+
<https://github.com/diofant/zz>`_ (version 0.9.0 or later required). This
|
|
57
57
|
module shouldn't crash the interpreter.
|
|
58
58
|
|
|
59
59
|
The gmp can be used as a `gmpy2`_/`python-flint`_ replacement to provide
|
|
@@ -2,7 +2,7 @@ Python-GMP
|
|
|
2
2
|
==========
|
|
3
3
|
|
|
4
4
|
Python extension module, providing bindings to the GNU GMP via the `ZZ library
|
|
5
|
-
<https://github.com/diofant/zz>`_ (version 0.
|
|
5
|
+
<https://github.com/diofant/zz>`_ (version 0.9.0 or later required). This
|
|
6
6
|
module shouldn't crash the interpreter.
|
|
7
7
|
|
|
8
8
|
The gmp can be used as a `gmpy2`_/`python-flint`_ replacement to provide
|
|
@@ -8,6 +8,8 @@ if os.getenv("T") == "gmpy2.mpz":
|
|
|
8
8
|
from gmpy2 import mpz
|
|
9
9
|
elif os.getenv("T") == "flint.fmpz":
|
|
10
10
|
from flint import fmpz as mpz
|
|
11
|
+
elif os.getenv("T") == "int":
|
|
12
|
+
mpz = int
|
|
11
13
|
else:
|
|
12
14
|
from gmp import mpz
|
|
13
15
|
|
|
@@ -34,8 +36,17 @@ def collatz1(n):
|
|
|
34
36
|
total += 1
|
|
35
37
|
return total
|
|
36
38
|
|
|
39
|
+
def collatz2(n):
|
|
40
|
+
total = 0
|
|
41
|
+
n = mpz(n)
|
|
42
|
+
while n > 1:
|
|
43
|
+
n = n*3 + 1 if n & one else n//2
|
|
44
|
+
total += 1
|
|
45
|
+
return total
|
|
46
|
+
|
|
47
|
+
|
|
37
48
|
runner = pyperf.Runner()
|
|
38
|
-
for f in [collatz0, collatz1]:
|
|
49
|
+
for f in [collatz0, collatz1, collatz2]:
|
|
39
50
|
for v in ["97", "871", "(1<<128)+31"]:
|
|
40
51
|
h = f"{f.__name__}({v})"
|
|
41
52
|
i = eval(v)
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
#else
|
|
13
13
|
# define MAX_CACHE_SIZE 0
|
|
14
14
|
#endif
|
|
15
|
-
#define
|
|
15
|
+
#define MAX_CACHED_SIZEOF 256
|
|
16
16
|
|
|
17
17
|
typedef struct {
|
|
18
18
|
MPZ_Object *gmp_cache[MAX_CACHE_SIZE + 1];
|
|
@@ -56,7 +56,7 @@ int OPT_PREFIX = 0x2;
|
|
|
56
56
|
PyObject *
|
|
57
57
|
MPZ_to_str(MPZ_Object *u, int base, int options)
|
|
58
58
|
{
|
|
59
|
-
size_t len;
|
|
59
|
+
size_t len = 0;
|
|
60
60
|
bool negative = zz_isneg(&u->z);
|
|
61
61
|
|
|
62
62
|
if (zz_sizeinbase(&u->z, base, &len)) {
|
|
@@ -140,60 +140,11 @@ MPZ_from_str(PyObject *obj, int base)
|
|
|
140
140
|
if (!str) {
|
|
141
141
|
return NULL; /* LCOV_EXCL_LINE */
|
|
142
142
|
}
|
|
143
|
-
if (base < 0) {
|
|
144
|
-
goto bad_base;
|
|
145
|
-
}
|
|
146
143
|
|
|
147
144
|
MPZ_Object *res = MPZ_new();
|
|
148
145
|
|
|
149
146
|
if (!res) {
|
|
150
|
-
return
|
|
151
|
-
}
|
|
152
|
-
while (isspace(*str)) {
|
|
153
|
-
str++;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
bool cast_negative = (str[0] == '-');
|
|
157
|
-
|
|
158
|
-
str += cast_negative;
|
|
159
|
-
if (str[0] == '+') {
|
|
160
|
-
str++;
|
|
161
|
-
}
|
|
162
|
-
if (str[0] == '0') {
|
|
163
|
-
if (base == 0) {
|
|
164
|
-
if (tolower(str[1]) == 'b') {
|
|
165
|
-
base = 2;
|
|
166
|
-
}
|
|
167
|
-
else if (tolower(str[1]) == 'o') {
|
|
168
|
-
base = 8;
|
|
169
|
-
}
|
|
170
|
-
else if (tolower(str[1]) == 'x') {
|
|
171
|
-
base = 16;
|
|
172
|
-
}
|
|
173
|
-
else if (!isspace(str[1]) && str[1] != '\0') {
|
|
174
|
-
goto err;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if ((tolower(str[1]) == 'b' && base == 2)
|
|
178
|
-
|| (tolower(str[1]) == 'o' && base == 8)
|
|
179
|
-
|| (tolower(str[1]) == 'x' && base == 16))
|
|
180
|
-
{
|
|
181
|
-
str += 2;
|
|
182
|
-
if (str[0] == '_') {
|
|
183
|
-
str++;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
goto skip_negation;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
skip_negation:
|
|
192
|
-
str -= cast_negative;
|
|
193
|
-
cast_negative = false;
|
|
194
|
-
}
|
|
195
|
-
if (base == 0) {
|
|
196
|
-
base = 10;
|
|
147
|
+
return NULL; /* LCOV_EXCL_LINE */
|
|
197
148
|
}
|
|
198
149
|
|
|
199
150
|
zz_err ret = zz_set_str(str, base, &res->z);
|
|
@@ -204,24 +155,26 @@ skip_negation:
|
|
|
204
155
|
return (MPZ_Object *)PyErr_NoMemory();
|
|
205
156
|
/* LCOV_EXCL_STOP */
|
|
206
157
|
}
|
|
158
|
+
else if (ret == ZZ_BUF) {
|
|
159
|
+
/* LCOV_EXCL_START */
|
|
160
|
+
PyErr_SetString(PyExc_OverflowError,
|
|
161
|
+
"too many digits in integer");
|
|
162
|
+
return NULL;
|
|
163
|
+
/* LCOV_EXCL_STOP */
|
|
164
|
+
}
|
|
207
165
|
else if (ret == ZZ_VAL) {
|
|
208
166
|
Py_DECREF(res);
|
|
209
|
-
if (2 <= base && base <= 36) {
|
|
210
|
-
err:
|
|
167
|
+
if (!base || (2 <= base && base <= 36)) {
|
|
211
168
|
PyErr_Format(PyExc_ValueError,
|
|
212
169
|
"invalid literal for mpz() with base %d: %.200R",
|
|
213
170
|
base, obj);
|
|
214
171
|
}
|
|
215
172
|
else {
|
|
216
|
-
bad_base:
|
|
217
173
|
PyErr_SetString(PyExc_ValueError,
|
|
218
174
|
"mpz base must be >= 2 and <= 36, or 0");
|
|
219
175
|
}
|
|
220
176
|
return NULL;
|
|
221
177
|
}
|
|
222
|
-
if (cast_negative) {
|
|
223
|
-
(void)zz_neg(&res->z, &res->z);
|
|
224
|
-
}
|
|
225
178
|
return res;
|
|
226
179
|
}
|
|
227
180
|
|
|
@@ -239,10 +192,22 @@ MPZ_from_int(PyObject *obj)
|
|
|
239
192
|
}
|
|
240
193
|
if (long_export.digits) {
|
|
241
194
|
res = MPZ_new();
|
|
242
|
-
if (!res
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
195
|
+
if (!res) {
|
|
196
|
+
return NULL; /* LCOV_EXCL_LINE */
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
zz_err ret = zz_import((size_t)long_export.ndigits,
|
|
200
|
+
long_export.digits, *int_layout, &res->z);
|
|
201
|
+
|
|
202
|
+
if (ret) {
|
|
203
|
+
/* LCOV_EXCL_START */
|
|
204
|
+
if (ret == ZZ_MEM) {
|
|
205
|
+
return (MPZ_Object *)PyErr_NoMemory();
|
|
206
|
+
}
|
|
207
|
+
PyErr_SetString(PyExc_OverflowError,
|
|
208
|
+
"too many digits in integer");
|
|
209
|
+
return NULL;
|
|
210
|
+
/* LCOV_EXCL_STOP */
|
|
246
211
|
}
|
|
247
212
|
if (long_export.negative) {
|
|
248
213
|
(void)zz_neg(&res->z, &res->z);
|
|
@@ -316,7 +281,7 @@ MPZ_to_int(MPZ_Object *u)
|
|
|
316
281
|
if (zz_get_str(&u->z, 16, buf)) {
|
|
317
282
|
/* LCOV_EXCL_START */
|
|
318
283
|
free(buf);
|
|
319
|
-
return
|
|
284
|
+
return PyErr_NoMemory();
|
|
320
285
|
/* LCOV_EXCL_STOP */
|
|
321
286
|
}
|
|
322
287
|
|
|
@@ -383,7 +348,7 @@ zz_get_bytes(const zz_t *u, size_t length, bool is_signed,
|
|
|
383
348
|
|
|
384
349
|
size_t gap = length - (nbits + bits_per_digit/8 - 1)/(bits_per_digit/8);
|
|
385
350
|
|
|
386
|
-
zz_export(u, bytes_layout, length - gap, *buffer + gap);
|
|
351
|
+
(void)zz_export(u, bytes_layout, length - gap, *buffer + gap);
|
|
387
352
|
memset(*buffer, is_negative ? 0xFF : 0, gap);
|
|
388
353
|
zz_clear(&tmp);
|
|
389
354
|
return ZZ_OK;
|
|
@@ -437,13 +402,18 @@ zz_set_bytes(const unsigned char *buffer, size_t length, bool is_signed,
|
|
|
437
402
|
if (!length) {
|
|
438
403
|
return zz_set(0, u);
|
|
439
404
|
}
|
|
440
|
-
|
|
441
|
-
|
|
405
|
+
|
|
406
|
+
zz_err ret = zz_import(length, buffer, bytes_layout, u);
|
|
407
|
+
|
|
408
|
+
if (ret) {
|
|
409
|
+
return ret; /* LCOV_EXCL_LINE */
|
|
442
410
|
}
|
|
443
411
|
(void)zz_abs(u, u);
|
|
444
412
|
if (is_signed && zz_bitlen(u) == 8*(size_t)length) {
|
|
445
413
|
zz_t tmp;
|
|
446
414
|
|
|
415
|
+
/* we assume, that bytes were created by zz_get_bytes(),
|
|
416
|
+
else there could be overflow in zz_mul_2exp() */
|
|
447
417
|
if (zz_init(&tmp) || zz_set(1, &tmp)
|
|
448
418
|
|| zz_mul_2exp(&tmp, 8*length, &tmp)
|
|
449
419
|
|| zz_sub(&tmp, u, u) || zz_neg(u, u))
|
|
@@ -490,19 +460,33 @@ MPZ_from_bytes(PyObject *obj, int is_little, int is_signed)
|
|
|
490
460
|
|
|
491
461
|
MPZ_Object *res = MPZ_new();
|
|
492
462
|
|
|
493
|
-
if (!res
|
|
463
|
+
if (!res) {
|
|
494
464
|
/* LCOV_EXCL_START */
|
|
495
465
|
Py_DECREF(bytes);
|
|
496
466
|
if (is_little) {
|
|
497
467
|
free(buffer);
|
|
498
468
|
}
|
|
499
|
-
|
|
500
|
-
return (MPZ_Object *)PyErr_NoMemory();
|
|
469
|
+
return NULL;
|
|
501
470
|
/* LCOV_EXCL_STOP */
|
|
502
471
|
}
|
|
472
|
+
|
|
473
|
+
zz_err ret = zz_set_bytes(buffer, (size_t)length, is_signed, &res->z);
|
|
474
|
+
|
|
475
|
+
Py_DECREF(bytes);
|
|
503
476
|
if (is_little) {
|
|
504
477
|
free(buffer);
|
|
505
478
|
}
|
|
479
|
+
if (ret) {
|
|
480
|
+
/* LCOV_EXCL_START */
|
|
481
|
+
Py_DECREF((PyObject *)res);
|
|
482
|
+
if (ret == ZZ_MEM) {
|
|
483
|
+
return (MPZ_Object *)PyErr_NoMemory();
|
|
484
|
+
}
|
|
485
|
+
PyErr_SetString(PyExc_OverflowError,
|
|
486
|
+
"too many digits in integer");
|
|
487
|
+
return NULL;
|
|
488
|
+
/* LCOV_EXCL_STOP */
|
|
489
|
+
}
|
|
506
490
|
return res;
|
|
507
491
|
}
|
|
508
492
|
|
|
@@ -676,7 +660,7 @@ dealloc(PyObject *self)
|
|
|
676
660
|
MPZ_Object *u = (MPZ_Object *)self;
|
|
677
661
|
|
|
678
662
|
if (global.gmp_cache_size < MAX_CACHE_SIZE
|
|
679
|
-
&& (u->z)
|
|
663
|
+
&& zz_sizeof(&u->z) <= MAX_CACHED_SIZEOF
|
|
680
664
|
&& MPZ_CheckExact(self))
|
|
681
665
|
{
|
|
682
666
|
global.gmp_cache[global.gmp_cache_size++] = u;
|
|
@@ -866,14 +850,20 @@ hash(PyObject *self)
|
|
|
866
850
|
return u->hash_cache;
|
|
867
851
|
}
|
|
868
852
|
|
|
869
|
-
|
|
870
|
-
|
|
853
|
+
zz_t w;
|
|
854
|
+
|
|
855
|
+
if (zz_init(&w)) {
|
|
856
|
+
return -1; /* LCOV_EXCL_LINE */
|
|
857
|
+
}
|
|
871
858
|
|
|
872
859
|
assert((int64_t)INT64_MAX > pyhash_modulus);
|
|
873
860
|
(void)zz_div(&u->z, (int64_t)pyhash_modulus, NULL, &w);
|
|
874
861
|
|
|
875
|
-
Py_hash_t r
|
|
862
|
+
Py_hash_t r;
|
|
876
863
|
|
|
864
|
+
assert(sizeof(Py_hash_t) == 8);
|
|
865
|
+
(void)zz_get(&w, (int64_t *)&r);
|
|
866
|
+
zz_clear(&w);
|
|
877
867
|
if (zz_isneg(&u->z) && r) {
|
|
878
868
|
r = -(pyhash_modulus - r);
|
|
879
869
|
}
|
|
@@ -883,23 +873,36 @@ hash(PyObject *self)
|
|
|
883
873
|
return u->hash_cache = r;
|
|
884
874
|
}
|
|
885
875
|
|
|
886
|
-
#define UNOP(suff, func)
|
|
887
|
-
static PyObject *
|
|
888
|
-
func(PyObject *self)
|
|
889
|
-
{
|
|
890
|
-
MPZ_Object *u = (MPZ_Object *)self;
|
|
891
|
-
MPZ_Object *res = MPZ_new();
|
|
892
|
-
|
|
893
|
-
if (res
|
|
894
|
-
|
|
895
|
-
}
|
|
896
|
-
|
|
876
|
+
#define UNOP(suff, func) \
|
|
877
|
+
static PyObject * \
|
|
878
|
+
func(PyObject *self) \
|
|
879
|
+
{ \
|
|
880
|
+
MPZ_Object *u = (MPZ_Object *)self; \
|
|
881
|
+
MPZ_Object *res = MPZ_new(); \
|
|
882
|
+
\
|
|
883
|
+
if (!res) { \
|
|
884
|
+
return NULL; \
|
|
885
|
+
} \
|
|
886
|
+
\
|
|
887
|
+
zz_err ret = zz_##suff(&u->z, &res->z); \
|
|
888
|
+
\
|
|
889
|
+
if (ret) { \
|
|
890
|
+
Py_CLEAR(res); \
|
|
891
|
+
if (ret == ZZ_BUF) { \
|
|
892
|
+
PyErr_SetString(PyExc_OverflowError, \
|
|
893
|
+
"too many digits in integer"); \
|
|
894
|
+
} \
|
|
895
|
+
else { \
|
|
896
|
+
PyErr_NoMemory(); \
|
|
897
|
+
} \
|
|
898
|
+
} \
|
|
899
|
+
return (PyObject *)res; \
|
|
897
900
|
}
|
|
898
901
|
|
|
899
902
|
UNOP(pos, plus)
|
|
900
903
|
UNOP(neg, nb_negative)
|
|
901
904
|
UNOP(abs, nb_absolute)
|
|
902
|
-
UNOP(invert, nb_invert)
|
|
905
|
+
UNOP(invert, nb_invert) /* may overflow */
|
|
903
906
|
|
|
904
907
|
PyObject *
|
|
905
908
|
to_int(PyObject *self)
|
|
@@ -972,17 +975,19 @@ to_bool(PyObject *self)
|
|
|
972
975
|
} \
|
|
973
976
|
ret = zz_##suff(&u->z, &v->z, &res->z); \
|
|
974
977
|
done: \
|
|
975
|
-
if (ret
|
|
976
|
-
goto end; \
|
|
977
|
-
} \
|
|
978
|
-
if (ret == ZZ_VAL) { \
|
|
979
|
-
Py_CLEAR(res); \
|
|
980
|
-
PyErr_SetString(PyExc_ZeroDivisionError, \
|
|
981
|
-
"division by zero"); \
|
|
982
|
-
} \
|
|
983
|
-
else { \
|
|
978
|
+
if (ret) { \
|
|
984
979
|
Py_CLEAR(res); \
|
|
985
|
-
|
|
980
|
+
if (ret == ZZ_VAL) { \
|
|
981
|
+
PyErr_SetString(PyExc_ZeroDivisionError, \
|
|
982
|
+
"division by zero"); \
|
|
983
|
+
} \
|
|
984
|
+
else if (ret == ZZ_BUF) { \
|
|
985
|
+
PyErr_SetString(PyExc_OverflowError, \
|
|
986
|
+
"too many digits in integer"); \
|
|
987
|
+
} \
|
|
988
|
+
else { \
|
|
989
|
+
PyErr_NoMemory(); \
|
|
990
|
+
} \
|
|
986
991
|
} \
|
|
987
992
|
end: \
|
|
988
993
|
Py_XDECREF((PyObject *)u); \
|
|
@@ -1032,6 +1037,7 @@ BINOP(mul, PyNumber_Multiply)
|
|
|
1032
1037
|
#define zz_quo_(u, v, w) zz_div((u), (v), (w), NULL)
|
|
1033
1038
|
#define zz_rem_(u, v, w) zz_div((u), (v), NULL, (w))
|
|
1034
1039
|
|
|
1040
|
+
/* can't overflow */
|
|
1035
1041
|
BINOP(quo_, PyNumber_FloorDivide)
|
|
1036
1042
|
BINOP(rem_, PyNumber_Remainder)
|
|
1037
1043
|
|
|
@@ -1149,6 +1155,8 @@ err:
|
|
|
1149
1155
|
if (cmp == ZZ_EQ && !zz_isodd(v) && !zz_iszero(q) && zz_isodd(q)) {
|
|
1150
1156
|
cmp = unexpect;
|
|
1151
1157
|
}
|
|
1158
|
+
/* No overflow is possible, since q can't have maximal value
|
|
1159
|
+
below (that means v==1) and r have same sign as v (with |r| < |v|) */
|
|
1152
1160
|
if (cmp == unexpect && (zz_add(q, 1, q) || zz_sub(r, v, r))) {
|
|
1153
1161
|
goto err; /* LCOV_EXCL_LINE */
|
|
1154
1162
|
}
|
|
@@ -1231,6 +1239,8 @@ tmp_clear:
|
|
|
1231
1239
|
}
|
|
1232
1240
|
}
|
|
1233
1241
|
shift += DBL_MANT_DIG;
|
|
1242
|
+
/* No overflow is possible in shifts, since shift value
|
|
1243
|
+
much smaller here than zz_get_bitcnt_max() */
|
|
1234
1244
|
if (shift > 0 && zz_mul_2exp(&a, (uint64_t)shift, &a)) {
|
|
1235
1245
|
goto tmp_clear; /* LCOV_EXCL_LINE */
|
|
1236
1246
|
}
|
|
@@ -1339,18 +1349,6 @@ numbers:
|
|
|
1339
1349
|
} \
|
|
1340
1350
|
} \
|
|
1341
1351
|
|
|
1342
|
-
#define CHECK_OP_INTv2(u, a) \
|
|
1343
|
-
if (MPZ_Check(a)) { \
|
|
1344
|
-
u = (MPZ_Object *)a; \
|
|
1345
|
-
Py_INCREF(u); \
|
|
1346
|
-
} \
|
|
1347
|
-
else if (PyLong_Check(a)) { \
|
|
1348
|
-
; \
|
|
1349
|
-
} \
|
|
1350
|
-
else { \
|
|
1351
|
-
goto end; \
|
|
1352
|
-
} \
|
|
1353
|
-
|
|
1354
1352
|
#define BINOP_INT(suff) \
|
|
1355
1353
|
static PyObject * \
|
|
1356
1354
|
nb_##suff(PyObject *self, PyObject *other) \
|
|
@@ -1363,7 +1361,7 @@ numbers:
|
|
|
1363
1361
|
res = MPZ_new(); \
|
|
1364
1362
|
zz_err ret = ZZ_OK; \
|
|
1365
1363
|
\
|
|
1366
|
-
if (
|
|
1364
|
+
if (res && (ret = zz_##suff(&u->z, &v->z, &res->z))) { \
|
|
1367
1365
|
/* LCOV_EXCL_START */ \
|
|
1368
1366
|
Py_CLEAR(res); \
|
|
1369
1367
|
if (ret == ZZ_VAL) { \
|
|
@@ -1385,90 +1383,7 @@ numbers:
|
|
|
1385
1383
|
return (PyObject *)res; \
|
|
1386
1384
|
}
|
|
1387
1385
|
|
|
1388
|
-
|
|
1389
|
-
static PyObject * \
|
|
1390
|
-
nb_##suff(PyObject *self, PyObject *other) \
|
|
1391
|
-
{ \
|
|
1392
|
-
MPZ_Object *u = NULL, *v = NULL, *res = NULL; \
|
|
1393
|
-
\
|
|
1394
|
-
CHECK_OP_INTv2(u, self); \
|
|
1395
|
-
CHECK_OP_INTv2(v, other); \
|
|
1396
|
-
\
|
|
1397
|
-
res = MPZ_new(); \
|
|
1398
|
-
if (!res) { \
|
|
1399
|
-
goto end; \
|
|
1400
|
-
} \
|
|
1401
|
-
\
|
|
1402
|
-
zz_err ret = ZZ_OK; \
|
|
1403
|
-
\
|
|
1404
|
-
if (!u) { \
|
|
1405
|
-
int error = PyLong_IsNegative(self) || zz_isneg(&v->z); \
|
|
1406
|
-
\
|
|
1407
|
-
if (!error) { \
|
|
1408
|
-
int64_t temp = PyLong_AsSdigit_t(self, &error); \
|
|
1409
|
-
\
|
|
1410
|
-
if (!error) { \
|
|
1411
|
-
ret = zz_i64_##suff(temp, &v->z, &res->z); \
|
|
1412
|
-
goto done; \
|
|
1413
|
-
} \
|
|
1414
|
-
} \
|
|
1415
|
-
u = MPZ_from_int(self); \
|
|
1416
|
-
if (!u) { \
|
|
1417
|
-
goto end; \
|
|
1418
|
-
} \
|
|
1419
|
-
} \
|
|
1420
|
-
if (!v) { \
|
|
1421
|
-
int error = zz_isneg(&u->z) || PyLong_IsNegative(other); \
|
|
1422
|
-
\
|
|
1423
|
-
if (!error) { \
|
|
1424
|
-
int64_t temp = PyLong_AsSdigit_t(other, &error); \
|
|
1425
|
-
\
|
|
1426
|
-
if (!error) { \
|
|
1427
|
-
ret = zz_##suff##_i64(&u->z, temp, &res->z); \
|
|
1428
|
-
goto done; \
|
|
1429
|
-
} \
|
|
1430
|
-
} \
|
|
1431
|
-
v = MPZ_from_int(other); \
|
|
1432
|
-
if (!v) { \
|
|
1433
|
-
goto end; \
|
|
1434
|
-
} \
|
|
1435
|
-
} \
|
|
1436
|
-
ret = zz_##suff(&u->z, &v->z, &res->z); \
|
|
1437
|
-
done: \
|
|
1438
|
-
if (ret) { \
|
|
1439
|
-
/* LCOV_EXCL_START */ \
|
|
1440
|
-
Py_CLEAR(res); \
|
|
1441
|
-
if (ret == ZZ_VAL) { \
|
|
1442
|
-
PyErr_SetString(PyExc_ValueError, \
|
|
1443
|
-
"negative shift count"); \
|
|
1444
|
-
} \
|
|
1445
|
-
else if (ret == ZZ_BUF) { \
|
|
1446
|
-
PyErr_SetString(PyExc_OverflowError, \
|
|
1447
|
-
"too many digits in integer"); \
|
|
1448
|
-
} \
|
|
1449
|
-
else { \
|
|
1450
|
-
PyErr_NoMemory(); \
|
|
1451
|
-
} \
|
|
1452
|
-
/* LCOV_EXCL_STOP */ \
|
|
1453
|
-
} \
|
|
1454
|
-
end: \
|
|
1455
|
-
Py_XDECREF((PyObject *)u); \
|
|
1456
|
-
Py_XDECREF((PyObject *)v); \
|
|
1457
|
-
return (PyObject *)res; \
|
|
1458
|
-
}
|
|
1459
|
-
|
|
1460
|
-
static inline zz_err
|
|
1461
|
-
zz_and_i64(const zz_t *u, int64_t v, zz_t *w)
|
|
1462
|
-
{
|
|
1463
|
-
if (zz_iszero(u) || !v) {
|
|
1464
|
-
return zz_set(0, w);
|
|
1465
|
-
}
|
|
1466
|
-
assert(!zz_isneg(u) && v > 0);
|
|
1467
|
-
return zz_set((int64_t)(u->digits[0] & (zz_digit_t)v), w);
|
|
1468
|
-
}
|
|
1469
|
-
#define zz_i64_and(x, y, r) zz_and_i64((y), (x), (r))
|
|
1470
|
-
|
|
1471
|
-
BINOP_INTv2(and)
|
|
1386
|
+
BINOP_INT(and)
|
|
1472
1387
|
BINOP_INT(or)
|
|
1473
1388
|
BINOP_INT(xor)
|
|
1474
1389
|
|
|
@@ -1479,12 +1394,12 @@ zz_lshift(const zz_t *u, const zz_t *v, zz_t *w)
|
|
|
1479
1394
|
return ZZ_VAL;
|
|
1480
1395
|
}
|
|
1481
1396
|
|
|
1482
|
-
|
|
1397
|
+
uint64_t shift;
|
|
1483
1398
|
|
|
1484
1399
|
if (zz_get(v, &shift)) {
|
|
1485
1400
|
return ZZ_BUF;
|
|
1486
1401
|
}
|
|
1487
|
-
return zz_mul_2exp(u,
|
|
1402
|
+
return zz_mul_2exp(u, shift, w);
|
|
1488
1403
|
}
|
|
1489
1404
|
|
|
1490
1405
|
static inline zz_err
|
|
@@ -1494,12 +1409,12 @@ zz_rshift(const zz_t *u, const zz_t *v, zz_t *w)
|
|
|
1494
1409
|
return ZZ_VAL;
|
|
1495
1410
|
}
|
|
1496
1411
|
|
|
1497
|
-
|
|
1412
|
+
uint64_t shift;
|
|
1498
1413
|
|
|
1499
1414
|
if (zz_get(v, &shift)) {
|
|
1500
1415
|
return zz_set(zz_isneg(u) ? -1 : 0, w);
|
|
1501
1416
|
}
|
|
1502
|
-
return zz_quo_2exp(u,
|
|
1417
|
+
return zz_quo_2exp(u, shift, w);
|
|
1503
1418
|
}
|
|
1504
1419
|
|
|
1505
1420
|
BINOP_INT(lshift)
|
|
@@ -1547,17 +1462,29 @@ power(PyObject *self, PyObject *other, PyObject *module)
|
|
|
1547
1462
|
Py_DECREF(vf);
|
|
1548
1463
|
return resf;
|
|
1549
1464
|
}
|
|
1550
|
-
res = MPZ_new();
|
|
1551
1465
|
|
|
1552
|
-
|
|
1466
|
+
uint64_t exp;
|
|
1553
1467
|
|
|
1554
|
-
if (
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1468
|
+
if (zz_get(&v->z, &exp)) {
|
|
1469
|
+
PyErr_SetString(PyExc_OverflowError,
|
|
1470
|
+
"too many digits in integer");
|
|
1471
|
+
}
|
|
1472
|
+
else {
|
|
1473
|
+
res = MPZ_new();
|
|
1474
|
+
if (res) {
|
|
1475
|
+
zz_err ret = zz_pow(&u->z, exp, &res->z);
|
|
1476
|
+
|
|
1477
|
+
if (ret) {
|
|
1478
|
+
Py_CLEAR(res);
|
|
1479
|
+
if (ret == ZZ_MEM) {
|
|
1480
|
+
PyErr_SetNone(PyExc_MemoryError); /* LCOV_EXCL_LINE */
|
|
1481
|
+
}
|
|
1482
|
+
else {
|
|
1483
|
+
PyErr_SetString(PyExc_OverflowError,
|
|
1484
|
+
"too many digits in integer");
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1561
1488
|
}
|
|
1562
1489
|
Py_DECREF(u);
|
|
1563
1490
|
Py_DECREF(v);
|
|
@@ -1871,58 +1798,67 @@ noop:
|
|
|
1871
1798
|
}
|
|
1872
1799
|
|
|
1873
1800
|
MPZ_Object *ndigits = NULL;
|
|
1874
|
-
zz_t exp, ten, p;
|
|
1875
|
-
|
|
1876
|
-
CHECK_OP_INT(ndigits, args[0]);
|
|
1877
1801
|
|
|
1878
|
-
if (
|
|
1879
|
-
|
|
1880
|
-
/* LCOV_EXCL_START */
|
|
1881
|
-
zz_clear(&exp);
|
|
1882
|
-
Py_DECREF(ndigits);
|
|
1883
|
-
return PyErr_NoMemory();
|
|
1884
|
-
/* LCOV_EXCL_STOP */
|
|
1885
|
-
}
|
|
1802
|
+
if (MPZ_Check(args[0])) {
|
|
1803
|
+
ndigits = (MPZ_Object *)plus(args[0]);
|
|
1886
1804
|
}
|
|
1887
1805
|
else {
|
|
1806
|
+
ndigits = MPZ_from_int(args[0]);
|
|
1807
|
+
}
|
|
1808
|
+
if (!ndigits) {
|
|
1809
|
+
return NULL;
|
|
1810
|
+
}
|
|
1811
|
+
if (!zz_isneg(&ndigits->z)) {
|
|
1888
1812
|
Py_DECREF(ndigits);
|
|
1889
1813
|
goto noop;
|
|
1890
1814
|
}
|
|
1891
|
-
|
|
1892
|
-
|
|
1815
|
+
|
|
1816
|
+
zz_t divisor;
|
|
1817
|
+
uint64_t exp;
|
|
1818
|
+
|
|
1819
|
+
(void)zz_neg(&ndigits->z, &ndigits->z);
|
|
1820
|
+
if (zz_init(&divisor) || zz_set(10, &divisor)) {
|
|
1893
1821
|
/* LCOV_EXCL_START */
|
|
1894
|
-
zz_clear(&
|
|
1895
|
-
zz_clear(&ten);
|
|
1822
|
+
zz_clear(&divisor);
|
|
1896
1823
|
return PyErr_NoMemory();
|
|
1897
1824
|
/* LCOV_EXCL_STOP */
|
|
1898
1825
|
}
|
|
1899
|
-
if (
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
zz_clear(&ten);
|
|
1903
|
-
zz_clear(&p);
|
|
1904
|
-
return PyErr_NoMemory();
|
|
1905
|
-
/* LCOV_EXCL_STOP */
|
|
1826
|
+
if (zz_get(&ndigits->z, &exp)) {
|
|
1827
|
+
zz_clear(&divisor);
|
|
1828
|
+
goto overflow;
|
|
1906
1829
|
}
|
|
1907
|
-
|
|
1908
|
-
|
|
1830
|
+
|
|
1831
|
+
zz_err ret = zz_pow(&divisor, exp, &divisor);
|
|
1832
|
+
|
|
1833
|
+
if (ret) {
|
|
1834
|
+
zz_clear(&divisor);
|
|
1835
|
+
Py_DECREF(ndigits);
|
|
1836
|
+
if (ret == ZZ_MEM) {
|
|
1837
|
+
return PyErr_NoMemory(); /* LCOV_EXCL_LINE */
|
|
1838
|
+
}
|
|
1839
|
+
overflow:
|
|
1840
|
+
PyErr_SetString(PyExc_OverflowError,
|
|
1841
|
+
"too many digits in integer");
|
|
1842
|
+
return NULL;
|
|
1843
|
+
}
|
|
1844
|
+
Py_DECREF(ndigits);
|
|
1909
1845
|
|
|
1910
1846
|
MPZ_Object *res = MPZ_new();
|
|
1911
1847
|
|
|
1912
1848
|
if (!res) {
|
|
1913
1849
|
/* LCOV_EXCL_START */
|
|
1914
|
-
zz_clear(&
|
|
1850
|
+
zz_clear(&divisor);
|
|
1915
1851
|
return NULL;
|
|
1916
1852
|
/* LCOV_EXCL_STOP */
|
|
1917
1853
|
}
|
|
1918
|
-
if (zz_divnear(&u->z, &
|
|
1854
|
+
if (zz_divnear(&u->z, &divisor, NULL, &res->z)) {
|
|
1919
1855
|
/* LCOV_EXCL_START */
|
|
1920
|
-
zz_clear(&
|
|
1856
|
+
zz_clear(&divisor);
|
|
1921
1857
|
Py_DECREF(res);
|
|
1922
1858
|
return PyErr_NoMemory();
|
|
1923
1859
|
/* LCOV_EXCL_STOP */
|
|
1924
1860
|
}
|
|
1925
|
-
zz_clear(&
|
|
1861
|
+
zz_clear(&divisor);
|
|
1926
1862
|
if (zz_sub(&u->z, &res->z, &res->z)) {
|
|
1927
1863
|
/* LCOV_EXCL_START */
|
|
1928
1864
|
Py_DECREF(res);
|
|
@@ -1930,8 +1866,6 @@ noop:
|
|
|
1930
1866
|
/* LCOV_EXCL_STOP */
|
|
1931
1867
|
}
|
|
1932
1868
|
return (PyObject *)res;
|
|
1933
|
-
end:
|
|
1934
|
-
return NULL;
|
|
1935
1869
|
}
|
|
1936
1870
|
|
|
1937
1871
|
static PyObject *
|
|
@@ -1950,8 +1884,8 @@ __sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored))
|
|
|
1950
1884
|
{
|
|
1951
1885
|
MPZ_Object *u = (MPZ_Object *)self;
|
|
1952
1886
|
|
|
1953
|
-
return PyLong_FromSize_t(sizeof(MPZ_Object)
|
|
1954
|
-
+ (
|
|
1887
|
+
return PyLong_FromSize_t(sizeof(MPZ_Object) - sizeof(zz_t)
|
|
1888
|
+
+ zz_sizeof(&u->z));
|
|
1955
1889
|
}
|
|
1956
1890
|
|
|
1957
1891
|
static PyObject *
|
|
@@ -2186,10 +2120,18 @@ gmp_lcm(PyObject *Py_UNUSED(module), PyObject *const *args, Py_ssize_t nargs)
|
|
|
2186
2120
|
Py_DECREF(arg);
|
|
2187
2121
|
continue;
|
|
2188
2122
|
}
|
|
2189
|
-
|
|
2123
|
+
|
|
2124
|
+
zz_err ret = zz_lcm(&res->z, &arg->z, &res->z);
|
|
2125
|
+
|
|
2126
|
+
if (ret) {
|
|
2190
2127
|
/* LCOV_EXCL_START */
|
|
2191
2128
|
Py_DECREF(res);
|
|
2192
2129
|
Py_DECREF(arg);
|
|
2130
|
+
if (ret == ZZ_BUF) {
|
|
2131
|
+
PyErr_SetString(PyExc_OverflowError,
|
|
2132
|
+
"too many digits in integer");
|
|
2133
|
+
return NULL;
|
|
2134
|
+
}
|
|
2193
2135
|
return PyErr_NoMemory();
|
|
2194
2136
|
/* LCOV_EXCL_STOP */
|
|
2195
2137
|
}
|
|
@@ -2221,7 +2163,7 @@ gmp_isqrt(PyObject *Py_UNUSED(module), PyObject *arg)
|
|
|
2221
2163
|
PyErr_SetString(PyExc_ValueError,
|
|
2222
2164
|
"isqrt() argument must be nonnegative");
|
|
2223
2165
|
}
|
|
2224
|
-
|
|
2166
|
+
else {
|
|
2225
2167
|
PyErr_NoMemory(); /* LCOV_EXCL_LINE */
|
|
2226
2168
|
}
|
|
2227
2169
|
end:
|
|
@@ -2250,11 +2192,11 @@ gmp_isqrt_rem(PyObject *Py_UNUSED(module), PyObject *arg)
|
|
|
2250
2192
|
if (ret == ZZ_OK) {
|
|
2251
2193
|
tup = PyTuple_Pack(2, root, rem);
|
|
2252
2194
|
}
|
|
2253
|
-
if (ret == ZZ_VAL) {
|
|
2195
|
+
else if (ret == ZZ_VAL) {
|
|
2254
2196
|
PyErr_SetString(PyExc_ValueError,
|
|
2255
2197
|
"isqrt() argument must be nonnegative");
|
|
2256
2198
|
}
|
|
2257
|
-
|
|
2199
|
+
else {
|
|
2258
2200
|
PyErr_NoMemory(); /* LCOV_EXCL_LINE */
|
|
2259
2201
|
}
|
|
2260
2202
|
end:
|
|
@@ -2278,17 +2220,24 @@ gmp_fac(PyObject *Py_UNUSED(module), PyObject *arg)
|
|
|
2278
2220
|
goto err;
|
|
2279
2221
|
}
|
|
2280
2222
|
|
|
2281
|
-
|
|
2223
|
+
uint64_t n;
|
|
2282
2224
|
|
|
2283
|
-
if (zz_get(&x->z, &n)
|
|
2225
|
+
if (zz_get(&x->z, &n)) {
|
|
2226
|
+
overflow:
|
|
2284
2227
|
PyErr_Format(PyExc_OverflowError,
|
|
2285
2228
|
"fac() argument should not exceed %ld",
|
|
2286
|
-
|
|
2229
|
+
ULONG_MAX);
|
|
2287
2230
|
goto err;
|
|
2288
2231
|
}
|
|
2289
2232
|
Py_XDECREF((PyObject *)x);
|
|
2290
|
-
|
|
2233
|
+
|
|
2234
|
+
zz_err ret = zz_fac((zz_digit_t)n, &res->z);
|
|
2235
|
+
|
|
2236
|
+
if (ret) {
|
|
2291
2237
|
/* LCOV_EXCL_START */
|
|
2238
|
+
if (ret == ZZ_BUF) {
|
|
2239
|
+
goto overflow;
|
|
2240
|
+
}
|
|
2292
2241
|
PyErr_NoMemory();
|
|
2293
2242
|
goto err;
|
|
2294
2243
|
/* LCOV_EXCL_STOP */
|
|
@@ -2321,11 +2270,10 @@ gmp_comb(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
|
|
|
2321
2270
|
goto err;
|
|
2322
2271
|
}
|
|
2323
2272
|
|
|
2324
|
-
|
|
2273
|
+
uint64_t n, k;
|
|
2325
2274
|
|
|
2326
|
-
if (
|
|
2327
|
-
|
|
2328
|
-
{
|
|
2275
|
+
if (zz_get(&x->z, &n) || zz_get(&y->z, &k)) {
|
|
2276
|
+
overflow:
|
|
2329
2277
|
PyErr_Format(PyExc_OverflowError,
|
|
2330
2278
|
"comb() arguments should not exceed %ld",
|
|
2331
2279
|
ULONG_MAX);
|
|
@@ -2333,8 +2281,14 @@ gmp_comb(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
|
|
|
2333
2281
|
}
|
|
2334
2282
|
Py_XDECREF((PyObject *)x);
|
|
2335
2283
|
Py_XDECREF((PyObject *)y);
|
|
2336
|
-
|
|
2284
|
+
|
|
2285
|
+
zz_err ret = zz_bin(n, k, &res->z);
|
|
2286
|
+
|
|
2287
|
+
if (ret) {
|
|
2337
2288
|
/* LCOV_EXCL_START */
|
|
2289
|
+
if (ret == ZZ_BUF) {
|
|
2290
|
+
goto overflow;
|
|
2291
|
+
}
|
|
2338
2292
|
PyErr_NoMemory();
|
|
2339
2293
|
goto err;
|
|
2340
2294
|
/* LCOV_EXCL_STOP */
|
|
@@ -2370,11 +2324,10 @@ gmp_perm(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
|
|
|
2370
2324
|
goto err;
|
|
2371
2325
|
}
|
|
2372
2326
|
|
|
2373
|
-
|
|
2327
|
+
uint64_t n, k;
|
|
2374
2328
|
|
|
2375
|
-
if (
|
|
2376
|
-
|
|
2377
|
-
{
|
|
2329
|
+
if (zz_get(&x->z, &n) || zz_get(&y->z, &k)) {
|
|
2330
|
+
overflow:
|
|
2378
2331
|
PyErr_Format(PyExc_OverflowError,
|
|
2379
2332
|
"perm() arguments should not exceed %ld",
|
|
2380
2333
|
ULONG_MAX);
|
|
@@ -2394,12 +2347,17 @@ gmp_perm(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
|
|
|
2394
2347
|
goto err;
|
|
2395
2348
|
/* LCOV_EXCL_STOP */
|
|
2396
2349
|
}
|
|
2397
|
-
|
|
2398
|
-
|
|
2350
|
+
|
|
2351
|
+
zz_err ret = zz_fac((zz_digit_t)n, &res->z);
|
|
2352
|
+
|
|
2353
|
+
if (ret || zz_fac((zz_digit_t)(n-k), &den->z)
|
|
2399
2354
|
|| zz_div(&res->z, &den->z, &res->z, NULL))
|
|
2400
2355
|
{
|
|
2401
2356
|
/* LCOV_EXCL_START */
|
|
2402
2357
|
Py_DECREF(den);
|
|
2358
|
+
if (ret == ZZ_BUF) {
|
|
2359
|
+
goto overflow;
|
|
2360
|
+
}
|
|
2403
2361
|
PyErr_NoMemory();
|
|
2404
2362
|
goto err;
|
|
2405
2363
|
/* LCOV_EXCL_STOP */
|
|
@@ -2507,14 +2465,12 @@ do_rnd:
|
|
|
2507
2465
|
}
|
|
2508
2466
|
|
|
2509
2467
|
zz_t tmp;
|
|
2468
|
+
zz_err ret = ZZ_OK;
|
|
2510
2469
|
|
|
2511
|
-
if (zz_init(&tmp) || shift
|
|
2512
|
-
|| zz_set((int64_t)shift, &tmp)
|
|
2513
|
-
|| zz_add(exp, &tmp, exp))
|
|
2514
|
-
{
|
|
2470
|
+
if (zz_init(&tmp) || (ret = zz_add(exp, shift, exp))) {
|
|
2515
2471
|
/* LCOV_EXCL_START */
|
|
2516
2472
|
zz_clear(&tmp);
|
|
2517
|
-
return
|
|
2473
|
+
return ret;
|
|
2518
2474
|
/* LCOV_EXCL_STOP */
|
|
2519
2475
|
}
|
|
2520
2476
|
zz_clear(&tmp);
|
|
@@ -2531,14 +2487,12 @@ do_rnd:
|
|
|
2531
2487
|
}
|
|
2532
2488
|
|
|
2533
2489
|
zz_t tmp;
|
|
2490
|
+
zz_err ret = ZZ_OK;
|
|
2534
2491
|
|
|
2535
|
-
if (zz_init(&tmp) || zbits
|
|
2536
|
-
|| zz_set((int64_t)zbits, &tmp)
|
|
2537
|
-
|| zz_add(exp, &tmp, exp))
|
|
2538
|
-
{
|
|
2492
|
+
if (zz_init(&tmp) || (ret = zz_add(exp, zbits, exp))) {
|
|
2539
2493
|
/* LCOV_EXCL_START */
|
|
2540
2494
|
zz_clear(&tmp);
|
|
2541
|
-
return
|
|
2495
|
+
return ret;
|
|
2542
2496
|
/* LCOV_EXCL_STOP */
|
|
2543
2497
|
}
|
|
2544
2498
|
zz_clear(&tmp);
|
|
@@ -2549,6 +2503,7 @@ do_rnd:
|
|
|
2549
2503
|
}
|
|
2550
2504
|
return ZZ_OK;
|
|
2551
2505
|
}
|
|
2506
|
+
|
|
2552
2507
|
static PyObject *
|
|
2553
2508
|
gmp__mpmath_normalize(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
|
|
2554
2509
|
{
|
|
@@ -2578,13 +2533,19 @@ gmp__mpmath_normalize(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
|
|
|
2578
2533
|
|
|
2579
2534
|
MPZ_Object *man = (MPZ_Object *)plus(args[1]);
|
|
2580
2535
|
MPZ_Object *exp = MPZ_from_int(args[2]);
|
|
2536
|
+
zz_err ret = ZZ_OK;
|
|
2581
2537
|
|
|
2582
|
-
if (!exp || !man || zz_mpmath_normalize(prec, rnd, &negative,
|
|
2583
|
-
|
|
2538
|
+
if (!exp || !man || (ret = zz_mpmath_normalize(prec, rnd, &negative,
|
|
2539
|
+
&man->z, &exp->z, &bc)))
|
|
2584
2540
|
{
|
|
2585
2541
|
/* LCOV_EXCL_START */
|
|
2586
2542
|
Py_XDECREF((PyObject *)man);
|
|
2587
2543
|
Py_XDECREF((PyObject *)exp);
|
|
2544
|
+
if (ret == ZZ_BUF) {
|
|
2545
|
+
PyErr_SetString(PyExc_OverflowError,
|
|
2546
|
+
"too many digits in integer");
|
|
2547
|
+
return NULL;
|
|
2548
|
+
}
|
|
2588
2549
|
return PyErr_NoMemory();
|
|
2589
2550
|
/* LCOV_EXCL_STOP */
|
|
2590
2551
|
}
|
|
@@ -2661,13 +2622,19 @@ gmp__mpmath_create(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
|
|
|
2661
2622
|
}
|
|
2662
2623
|
|
|
2663
2624
|
MPZ_Object *exp = MPZ_from_int(args[1]);
|
|
2625
|
+
zz_err ret = ZZ_OK;
|
|
2664
2626
|
|
|
2665
|
-
if (!exp || zz_mpmath_normalize(prec, rnd, &negative,
|
|
2666
|
-
|
|
2627
|
+
if (!exp || (ret = zz_mpmath_normalize(prec, rnd, &negative,
|
|
2628
|
+
&man->z, &exp->z, &bc)))
|
|
2667
2629
|
{
|
|
2668
2630
|
/* LCOV_EXCL_START */
|
|
2669
2631
|
Py_DECREF(man);
|
|
2670
2632
|
Py_XDECREF((PyObject *)exp);
|
|
2633
|
+
if (ret == ZZ_BUF) {
|
|
2634
|
+
PyErr_SetString(PyExc_OverflowError,
|
|
2635
|
+
"too many digits in integer");
|
|
2636
|
+
return NULL;
|
|
2637
|
+
}
|
|
2671
2638
|
return PyErr_NoMemory();
|
|
2672
2639
|
/* LCOV_EXCL_STOP */
|
|
2673
2640
|
}
|
|
@@ -5,7 +5,7 @@ def pytest_configure(config):
|
|
|
5
5
|
from hypothesis import settings
|
|
6
6
|
|
|
7
7
|
default = settings.get_profile("default")
|
|
8
|
-
settings.register_profile("default", settings(default, deadline=
|
|
8
|
+
settings.register_profile("default", settings(default, deadline=3000))
|
|
9
9
|
ci = settings.get_profile("ci")
|
|
10
10
|
if platform.python_implementation() != "GraalVM":
|
|
11
11
|
ci = settings(ci, max_examples=10000)
|
|
@@ -720,22 +720,23 @@ def test_power_errors():
|
|
|
720
720
|
pow(object(), mpz(321))
|
|
721
721
|
if platform.python_implementation() == "GraalVM":
|
|
722
722
|
return # issue oracle/graalpython#551
|
|
723
|
+
with pytest.raises(OverflowError):
|
|
724
|
+
pow(mpz(2), mpz(1<<64))
|
|
723
725
|
if BITCNT_MAX < (1<<64) - 1:
|
|
724
|
-
with pytest.raises(
|
|
726
|
+
with pytest.raises(OverflowError):
|
|
725
727
|
pow(mpz(1<<64), (1<<31) - 1)
|
|
726
|
-
with pytest.raises(
|
|
728
|
+
with pytest.raises(OverflowError):
|
|
727
729
|
pow(mpz(1<<64), (1<<31))
|
|
730
|
+
with pytest.raises(OverflowError):
|
|
731
|
+
mpz(1) << ((1 << 63) - 1)
|
|
728
732
|
else:
|
|
729
|
-
with pytest.raises(
|
|
733
|
+
with pytest.raises(OverflowError):
|
|
730
734
|
pow(mpz(1<<64), (1<<63) - 1)
|
|
731
735
|
if platform.system() != "Darwin":
|
|
732
|
-
with pytest.raises(
|
|
736
|
+
with pytest.raises(OverflowError):
|
|
733
737
|
pow(mpz(1<<64), (1<<63))
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
if platform.system() != "Darwin":
|
|
737
|
-
with pytest.raises(MemoryError):
|
|
738
|
-
mpz(1) << ((1 << 63) - 1)
|
|
738
|
+
with pytest.raises(OverflowError):
|
|
739
|
+
mpz(1) << ((1 << 64) - 1)
|
|
739
740
|
|
|
740
741
|
|
|
741
742
|
@given(bigints(), integers(max_value=12345))
|
|
@@ -981,6 +982,12 @@ def test_round_interface():
|
|
|
981
982
|
x.__round__(1, 2)
|
|
982
983
|
with pytest.raises(TypeError):
|
|
983
984
|
x.__round__(1j)
|
|
985
|
+
with pytest.raises(OverflowError):
|
|
986
|
+
x.__round__((-1<<64) + 1)
|
|
987
|
+
with pytest.raises(OverflowError):
|
|
988
|
+
x.__round__((-1<<62))
|
|
989
|
+
with pytest.raises(OverflowError):
|
|
990
|
+
x.__round__(-1<<127)
|
|
984
991
|
|
|
985
992
|
|
|
986
993
|
@pytest.mark.skipif(platform.python_implementation() == "PyPy",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|