|
|
1c15d4c |
--- src/_fastmath.c
|
|
|
1c15d4c |
+++ src/_fastmath.c
|
|
|
d41955b |
@@ -58,6 +58,20 @@
|
|
|
d41955b |
#define INLINE inline
|
|
|
d41955b |
#endif
|
|
|
d41955b |
|
|
|
d41955b |
+#if PY_VERSION_HEX >= 0x030C0000
|
|
|
d41955b |
+/* Code cribbed from python's internal/pycore_long.h */
|
|
|
d41955b |
+/* Long value tag bits:
|
|
|
d41955b |
+ * * 0-1: Sign bits value = (1-sign), ie. negative=2, positive=0, zero=1.
|
|
|
d41955b |
+ * * 2: Reserved for immortality bit
|
|
|
d41955b |
+ * * 3+ Unsigned digit count
|
|
|
d41955b |
+ * */
|
|
|
d41955b |
+#define SIGN_MASK 3
|
|
|
d41955b |
+#define SIGN_ZERO 1
|
|
|
d41955b |
+#define SIGN_NEGATIVE 2
|
|
|
d41955b |
+#define NON_SIZE_BITS 3
|
|
|
d41955b |
+#define TAG_FROM_SIGN_AND_SIZE(sign, size) ((1 - (sign)) | ((size) << NON_SIZE_BITS))
|
|
|
d41955b |
+#endif
|
|
|
d41955b |
+
|
|
|
d41955b |
static unsigned int sieve_base[10000];
|
|
|
d41955b |
static int rabinMillerTest (mpz_t n, int rounds, PyObject *randfunc);
|
|
|
d41955b |
|
|
|
d41955b |
@@ -70,13 +84,24 @@ longObjToMPZ (mpz_t m, PyLongObject * p)
|
|
|
1c15d4c |
mpz_init (temp);
|
|
|
1c15d4c |
mpz_init (temp2);
|
|
|
1c15d4c |
#ifdef IS_PY3K
|
|
|
1c15d4c |
- if (p->ob_base.ob_size > 0) {
|
|
|
1c15d4c |
- size = p->ob_base.ob_size;
|
|
|
d41955b |
+#if PY_VERSION_HEX < 0x030C0000
|
|
|
1c15d4c |
+ if (Py_SIZE(p) > 0) {
|
|
|
1c15d4c |
+ size = Py_SIZE(p);
|
|
|
1c15d4c |
negative = 1;
|
|
|
1c15d4c |
} else {
|
|
|
1c15d4c |
- size = -p->ob_base.ob_size;
|
|
|
1c15d4c |
+ size = -Py_SIZE(p);
|
|
|
d41955b |
+ negative = -1;
|
|
|
d41955b |
+ }
|
|
|
d41955b |
+#else
|
|
|
d41955b |
+ size = p->long_value.lv_tag >> NON_SIZE_BITS;
|
|
|
d41955b |
+ if ((p->long_value.lv_tag & SIGN_MASK) == SIGN_NEGATIVE) {
|
|
|
1c15d4c |
negative = -1;
|
|
|
d41955b |
+ } else if ((p->long_value.lv_tag & SIGN_MASK) == SIGN_ZERO) {
|
|
|
d41955b |
+ negative = 0;
|
|
|
d41955b |
+ } else {
|
|
|
d41955b |
+ negative = 1;
|
|
|
1c15d4c |
}
|
|
|
d41955b |
+#endif
|
|
|
1c15d4c |
#else
|
|
|
d41955b |
if (p->ob_size > 0) {
|
|
|
d41955b |
size = p->ob_size;
|
|
|
d41955b |
@@ -89,7 +114,11 @@ longObjToMPZ (mpz_t m, PyLongObject * p)
|
|
|
1c15d4c |
mpz_set_ui (m, 0);
|
|
|
1c15d4c |
for (i = 0; i < size; i++)
|
|
|
1c15d4c |
{
|
|
|
1c15d4c |
+#if PY_VERSION_HEX < 0x030C0000
|
|
|
1c15d4c |
mpz_set_ui (temp, p->ob_digit[i]);
|
|
|
1c15d4c |
+#else
|
|
|
1c15d4c |
+ mpz_set_ui (temp, p->long_value.ob_digit[i]);
|
|
|
1c15d4c |
+#endif
|
|
|
1c15d4c |
#ifdef IS_PY3K
|
|
|
1c15d4c |
mpz_mul_2exp (temp2, temp, PyLong_SHIFT * i);
|
|
|
1c15d4c |
#else
|
|
|
d41955b |
@@ -123,7 +152,11 @@ mpzToLongObj (mpz_t m)
|
|
|
1c15d4c |
for (i = 0; i < size; i++)
|
|
|
1c15d4c |
{
|
|
|
1c15d4c |
#ifdef IS_PY3K
|
|
|
1c15d4c |
+#if PY_VERSION_HEX < 0x030C0000
|
|
|
1c15d4c |
l->ob_digit[i] = (digit) (mpz_get_ui (temp) & PyLong_MASK);
|
|
|
1c15d4c |
+#else
|
|
|
1c15d4c |
+ l->long_value.ob_digit[i] = (digit) (mpz_get_ui (temp) & PyLong_MASK);
|
|
|
1c15d4c |
+#endif
|
|
|
1c15d4c |
mpz_fdiv_q_2exp (temp, temp, PyLong_SHIFT);
|
|
|
1c15d4c |
#else
|
|
|
1c15d4c |
l->ob_digit[i] = (digit) (mpz_get_ui (temp) & MASK);
|
|
|
d41955b |
@@ -131,11 +164,19 @@ mpzToLongObj (mpz_t m)
|
|
|
1c15d4c |
#endif
|
|
|
1c15d4c |
}
|
|
|
1c15d4c |
i = size;
|
|
|
1c15d4c |
+#if PY_VERSION_HEX < 0x030C0000
|
|
|
1c15d4c |
while ((i > 0) && (l->ob_digit[i - 1] == 0))
|
|
|
1c15d4c |
+#else
|
|
|
1c15d4c |
+ while ((i > 0) && (l->long_value.ob_digit[i - 1] == 0))
|
|
|
1c15d4c |
+#endif
|
|
|
1c15d4c |
i--;
|
|
|
1c15d4c |
#ifdef IS_PY3K
|
|
|
d41955b |
+#if PY_VERSION_HEX < 0x030C0000
|
|
|
1c15d4c |
l->ob_base.ob_size = i * sgn;
|
|
|
1c15d4c |
#else
|
|
|
d41955b |
+ l->long_value.lv_tag = TAG_FROM_SIGN_AND_SIZE(sgn, (size_t)i);
|
|
|
1c15d4c |
+#endif
|
|
|
1c15d4c |
+#else
|
|
|
1c15d4c |
l->ob_size = i * sgn;
|
|
|
1c15d4c |
#endif
|
|
|
1c15d4c |
mpz_clear (temp);
|