Merge pull request #3377 from jepler/support-udecimal
core: Enable some features neede for a port of python3's decimal module
This commit is contained in:
commit
bbd802940e
@ -185,6 +185,7 @@ typedef long mp_off_t;
|
|||||||
// Turning off FULL_BUILD removes some functionality to reduce flash size on tiny SAMD21s
|
// Turning off FULL_BUILD removes some functionality to reduce flash size on tiny SAMD21s
|
||||||
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (CIRCUITPY_FULL_BUILD)
|
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (CIRCUITPY_FULL_BUILD)
|
||||||
#define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD)
|
#define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD)
|
||||||
|
#define MICROPY_PY_BUILTINS_POW3 (CIRCUITPY_FULL_BUILD)
|
||||||
#define MICROPY_COMP_FSTRING_LITERAL (MICROPY_CPYTHON_COMPAT)
|
#define MICROPY_COMP_FSTRING_LITERAL (MICROPY_CPYTHON_COMPAT)
|
||||||
#define MICROPY_MODULE_WEAK_LINKS (CIRCUITPY_FULL_BUILD)
|
#define MICROPY_MODULE_WEAK_LINKS (CIRCUITPY_FULL_BUILD)
|
||||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD)
|
#define MICROPY_PY_ALL_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD)
|
||||||
|
3
py/mpz.h
3
py/mpz.h
@ -135,6 +135,9 @@ void mpz_xor_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs);
|
|||||||
void mpz_divmod_inpl(mpz_t *dest_quo, mpz_t *dest_rem, const mpz_t *lhs, const mpz_t *rhs);
|
void mpz_divmod_inpl(mpz_t *dest_quo, mpz_t *dest_rem, const mpz_t *lhs, const mpz_t *rhs);
|
||||||
|
|
||||||
static inline size_t mpz_max_num_bits(const mpz_t *z) { return z->len * MPZ_DIG_SIZE; }
|
static inline size_t mpz_max_num_bits(const mpz_t *z) { return z->len * MPZ_DIG_SIZE; }
|
||||||
|
static inline size_t mpz_num_bits(const mpz_t *z) {
|
||||||
|
size_t last_bits = (8 * (sizeof(long) - sizeof(mpz_dig_t))) - __builtin_clzl(z->dig[z->len-1]);
|
||||||
|
return z->len * MPZ_DIG_SIZE + last_bits; }
|
||||||
mp_int_t mpz_hash(const mpz_t *z);
|
mp_int_t mpz_hash(const mpz_t *z);
|
||||||
bool mpz_as_int_checked(const mpz_t *z, mp_int_t *value);
|
bool mpz_as_int_checked(const mpz_t *z, mp_int_t *value);
|
||||||
bool mpz_as_uint_checked(const mpz_t *z, mp_uint_t *value);
|
bool mpz_as_uint_checked(const mpz_t *z, mp_uint_t *value);
|
||||||
|
25
py/objint.c
25
py/objint.c
@ -457,6 +457,28 @@ mp_obj_t mp_obj_int_binary_op_extra_cases(mp_binary_op_t op, mp_obj_t lhs_in, mp
|
|||||||
return MP_OBJ_NULL; // op not supported
|
return MP_OBJ_NULL; // op not supported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MICROPY_CPYTHON_COMPAT
|
||||||
|
STATIC mp_obj_t int_bit_length(mp_obj_t self_in) {
|
||||||
|
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
|
||||||
|
if (!MP_OBJ_IS_SMALL_INT(self_in)) {
|
||||||
|
return mp_obj_int_bit_length_impl(self_in);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
mp_int_t int_val = MP_OBJ_SMALL_INT_VALUE(self_in);
|
||||||
|
mp_uint_t value =
|
||||||
|
(int_val == 0) ? 0 :
|
||||||
|
(int_val == MP_SMALL_INT_MIN) ? 8 * sizeof(mp_int_t) :
|
||||||
|
(int_val < 0) ? 8 * sizeof(long) - __builtin_clzl(-int_val) :
|
||||||
|
8 * sizeof(long) - __builtin_clzl(int_val);
|
||||||
|
return mp_obj_new_int_from_uint(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(int_bit_length_obj, int_bit_length);
|
||||||
|
#endif
|
||||||
|
|
||||||
// this is a classmethod
|
// this is a classmethod
|
||||||
STATIC mp_obj_t int_from_bytes(size_t n_args, const mp_obj_t *args) {
|
STATIC mp_obj_t int_from_bytes(size_t n_args, const mp_obj_t *args) {
|
||||||
// TODO: Support signed param (assumes signed=False at the moment)
|
// TODO: Support signed param (assumes signed=False at the moment)
|
||||||
@ -537,6 +559,9 @@ STATIC mp_obj_t int_to_bytes(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
|
|||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(int_to_bytes_obj, 3, int_to_bytes);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(int_to_bytes_obj, 3, int_to_bytes);
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t int_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t int_locals_dict_table[] = {
|
||||||
|
#if MICROPY_CPYTHON_COMPAT
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_bit_length), MP_ROM_PTR(&int_bit_length_obj) },
|
||||||
|
#endif
|
||||||
{ MP_ROM_QSTR(MP_QSTR_from_bytes), MP_ROM_PTR(&int_from_bytes_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_from_bytes), MP_ROM_PTR(&int_from_bytes_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_to_bytes), MP_ROM_PTR(&int_to_bytes_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_to_bytes), MP_ROM_PTR(&int_to_bytes_obj) },
|
||||||
};
|
};
|
||||||
|
@ -60,6 +60,7 @@ void mp_obj_int_buffer_overflow_check(mp_obj_t self_in, size_t nbytes, bool is_s
|
|||||||
void mp_small_int_buffer_overflow_check(mp_int_t val, size_t nbytes, bool is_signed);
|
void mp_small_int_buffer_overflow_check(mp_int_t val, size_t nbytes, bool is_signed);
|
||||||
|
|
||||||
mp_int_t mp_obj_int_hash(mp_obj_t self_in);
|
mp_int_t mp_obj_int_hash(mp_obj_t self_in);
|
||||||
|
mp_obj_t mp_obj_int_bit_length_impl(mp_obj_t self_in);
|
||||||
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf);
|
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf);
|
||||||
void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf);
|
void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf);
|
||||||
int mp_obj_int_sign(mp_obj_t self_in);
|
int mp_obj_int_sign(mp_obj_t self_in);
|
||||||
|
@ -45,6 +45,17 @@
|
|||||||
const mp_obj_int_t mp_maxsize_obj = {{&mp_type_int}, MP_SSIZE_MAX};
|
const mp_obj_int_t mp_maxsize_obj = {{&mp_type_int}, MP_SSIZE_MAX};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mp_obj_t mp_obj_int_bit_length_impl(mp_obj_t self_in) {
|
||||||
|
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int));
|
||||||
|
mp_obj_int_t *self = self_in;
|
||||||
|
long long val = self->val;
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(
|
||||||
|
(val == 0) ? 0 :
|
||||||
|
(val == MP_SMALL_INT_MIN) ? 8 * sizeof(long long) :
|
||||||
|
(val < 0) ? 8 * sizeof(long long) - __builtin_clzll(-val) :
|
||||||
|
8 * sizeof(long long) - __builtin_clzll(val));
|
||||||
|
}
|
||||||
|
|
||||||
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf) {
|
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf) {
|
||||||
int delta = 1;
|
int delta = 1;
|
||||||
if (!big_endian) {
|
if (!big_endian) {
|
||||||
|
@ -107,6 +107,12 @@ char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size,
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mp_obj_t mp_obj_int_bit_length_impl(mp_obj_t self_in) {
|
||||||
|
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int));
|
||||||
|
mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(mpz_num_bits(&self->mpz));
|
||||||
|
}
|
||||||
|
|
||||||
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf) {
|
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf) {
|
||||||
mp_obj_int_t *o = mp_obj_int_new_mpz();
|
mp_obj_int_t *o = mp_obj_int_new_mpz();
|
||||||
mpz_set_from_bytes(&o->mpz, big_endian, len, buf);
|
mpz_set_from_bytes(&o->mpz, big_endian, len, buf);
|
||||||
|
4
tests/basics/bit_length.py
Normal file
4
tests/basics/bit_length.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
for i in range(129):
|
||||||
|
j = (1 << i)
|
||||||
|
print(i, (j-1).bit_length(), (j).bit_length(), (j+1).bit_length())
|
||||||
|
print(i, (-j-1).bit_length(), (-j).bit_length(), (-j+1).bit_length())
|
@ -1,14 +1,14 @@
|
|||||||
########
|
########
|
||||||
object <function> is of type function
|
object <function> is of type function
|
||||||
object <class 'int'> is of type type
|
object <class 'int'> is of type type
|
||||||
|
bit_length -- <function>
|
||||||
from_bytes -- <classmethod>
|
from_bytes -- <classmethod>
|
||||||
to_bytes -- <function>
|
to_bytes -- <function>
|
||||||
object 1 is of type int
|
object 1 is of type int
|
||||||
|
bit_length -- <function>
|
||||||
from_bytes -- <classmethod>
|
from_bytes -- <classmethod>
|
||||||
to_bytes -- <function>
|
to_bytes -- <function>
|
||||||
object <module 'micropython'> is of type module
|
object <module 'micropython'> is of type module
|
||||||
__name__ -- micropython
|
__name__ -- micropython
|
||||||
const -- <function>
|
|
||||||
opt_level -- <function>
|
|
||||||
########
|
########
|
||||||
done
|
done
|
||||||
|
@ -12,7 +12,7 @@ Use \.\+
|
|||||||
'abc'
|
'abc'
|
||||||
>>> x = 5
|
>>> x = 5
|
||||||
>>> x.
|
>>> x.
|
||||||
from_bytes to_bytes
|
bit_length from_bytes to_bytes
|
||||||
>>> x.[K[K
|
>>> x.[K[K
|
||||||
>>> x.__class__
|
>>> x.__class__
|
||||||
<class 'int'>
|
<class 'int'>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user