Skip to content

Commit

Permalink
Merge pull request #539 from skirpichev/use-mpn_get_str/404
Browse files Browse the repository at this point in the history
Optimize to_binary() function and to_bytes() method
  • Loading branch information
casevh authored Dec 26, 2024
2 parents d107d98 + 2524ada commit dc08582
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 8 deletions.
6 changes: 4 additions & 2 deletions src/gmpy2_binary.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,15 +260,17 @@ GMPy_MPZ_To_Binary(MPZ_Object *self)
goto done;
}

size = ((mpz_sizeinbase(self->z, 2) + 7) / 8) + 2;
size = mpz_sizeinbase(self->z, 256) + 2;

TEMP_ALLOC(buffer, size);
buffer[0] = 0x01;
if (sgn > 0)
buffer[1] = 0x01;
else
buffer[1] = 0x02;
mpz_export(buffer+2, NULL, -1, sizeof(char), 0, 0, self->z);
mpn_get_str((unsigned char *)(buffer + 2), 256,
self->z->_mp_d, Py_ABS(self->z->_mp_size));
revstr(buffer, 2, size - 1);

done:
result = PyBytes_FromStringAndSize(buffer, size);
Expand Down
17 changes: 17 additions & 0 deletions src/gmpy2_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -726,3 +726,20 @@ GMPy_Context_##NAME(PyObject *self, PyObject *args) \
} \
return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); \
}

#define SWAP(T, a, b) \
do { \
T tmp = a; \
a = b; \
b = tmp; \
} while (0);

static inline void
revstr(char *s, size_t l, size_t r)
{
while (l < r) {
SWAP(char, s[l], s[r]);
l++;
r--;
}
}
12 changes: 6 additions & 6 deletions src/gmpy2_mpz_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1986,15 +1986,15 @@ GMPy_MPZ_Method_To_Bytes(PyObject *self, PyObject *const *args,
return NULL;
}
buffer = PyBytes_AS_STRING(bytes);
memset(buffer, 0, length);
memset(buffer, is_negative ? 0xFF : 0, gap);

if (is_big) {
mpz_export(buffer + gap, NULL, 1, sizeof(char), 0, 0, *px);
if ((*px)->_mp_size) {
mpn_get_str((unsigned char *)(buffer + gap), 256,
(*px)->_mp_d, (*px)->_mp_size);
}
else {
mpz_export(buffer, NULL, -1, sizeof(char), 0, 0, *px);
if (!is_big && length) {
revstr(buffer, 0, length - 1);
}

if (is_negative) {
mpz_clear(tmp);
}
Expand Down

0 comments on commit dc08582

Please sign in to comment.