py/mpz: Implement mpz_set_from_bytes() as a foundation for int.from_bytes().
This commit is contained in:
parent
5298472fee
commit
1b42f5251f
31
py/mpz.c
31
py/mpz.c
|
@ -909,6 +909,37 @@ mp_uint_t mpz_set_from_str(mpz_t *z, const char *str, mp_uint_t len, bool neg, m
|
|||
return cur - str;
|
||||
}
|
||||
|
||||
void mpz_set_from_bytes(mpz_t *z, bool big_endian, mp_uint_t len, const byte *buf) {
|
||||
int delta = 1;
|
||||
if (big_endian) {
|
||||
buf += len - 1;
|
||||
delta = -1;
|
||||
}
|
||||
|
||||
mpz_need_dig(z, (len * 8 + DIG_SIZE - 1) / DIG_SIZE);
|
||||
|
||||
mpz_dig_t d = 0;
|
||||
int num_bits = 0;
|
||||
z->neg = 0;
|
||||
z->len = 0;
|
||||
while (len) {
|
||||
while (len && num_bits < DIG_SIZE) {
|
||||
d |= *buf << num_bits;
|
||||
num_bits += 8;
|
||||
buf += delta;
|
||||
len--;
|
||||
}
|
||||
z->dig[z->len++] = d & DIG_MASK;
|
||||
// Need this #if because it's C undefined behavior to do: uint32_t >> 32
|
||||
#if DIG_SIZE != 8 && DIG_SIZE != 16 && DIG_SIZE != 32
|
||||
d >>= DIG_SIZE;
|
||||
#else
|
||||
d = 0;
|
||||
#endif
|
||||
num_bits -= DIG_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
bool mpz_is_zero(const mpz_t *z) {
|
||||
return z->len == 0;
|
||||
}
|
||||
|
|
1
py/mpz.h
1
py/mpz.h
|
@ -109,6 +109,7 @@ void mpz_set_from_ll(mpz_t *z, long long i, bool is_signed);
|
|||
void mpz_set_from_float(mpz_t *z, mp_float_t src);
|
||||
#endif
|
||||
mp_uint_t mpz_set_from_str(mpz_t *z, const char *str, mp_uint_t len, bool neg, mp_uint_t base);
|
||||
void mpz_set_from_bytes(mpz_t *z, bool big_endian, mp_uint_t len, const byte *buf);
|
||||
|
||||
bool mpz_is_zero(const mpz_t *z);
|
||||
int mpz_cmp(const mpz_t *lhs, const mpz_t *rhs);
|
||||
|
|
Loading…
Reference in New Issue