|
31 | 31 |
|
32 | 32 | #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_MPZ |
33 | 33 |
|
| 34 | +#include "py/objint.h" |
| 35 | +#include "py/runtime.h" |
| 36 | +#define debug_printf(...) // mp_printf(&mp_plat_print, __VA_ARGS__); mp_printf(&mp_plat_print, " | %d at %s\n", __LINE__, __FILE__); |
| 37 | + |
34 | 38 | #define DIG_SIZE (MPZ_DIG_SIZE) |
35 | 39 | #define DIG_MASK ((MPZ_LONG_1 << DIG_SIZE) - 1) |
36 | 40 | #define DIG_MSB (MPZ_LONG_1 << (DIG_SIZE - 1)) |
@@ -851,19 +855,58 @@ size_t mpz_set_from_str(mpz_t *z, const char *str, size_t len, bool neg, unsigne |
851 | 855 | } |
852 | 856 |
|
853 | 857 | void mpz_set_from_bytes(mpz_t *z, bool big_endian, bool is_signed, size_t len, const byte *buf) { |
854 | | - int delta = 1; |
855 | | - if (big_endian) { |
856 | | - buf += len - 1; |
857 | | - delta = -1; |
| 858 | + debug_printf("MPZ"); |
| 859 | + debug_printf("big_endian:%d, is_signed:%d, len:%d", big_endian, is_signed, len) |
| 860 | + debug_printf("buf %X %X %X %X %X %X", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]) |
| 861 | + union { |
| 862 | + long long value; |
| 863 | + byte buf[sizeof(long long)]; |
| 864 | + } result = {0}; |
| 865 | + if (len > sizeof(result)) { |
| 866 | + mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("big-int overflow")); |
858 | 867 | } |
859 | | - |
| 868 | + if (big_endian) { |
| 869 | + debug_printf("big_endian"); |
| 870 | + reverce_memcpy(&result, buf, len); |
| 871 | + } else { // little-endian |
| 872 | + debug_printf("little-endian"); |
| 873 | + memcpy(&result, buf, len); |
| 874 | + } |
| 875 | + |
| 876 | + if ((is_signed) && (sizeof(result) > len) && (result.buf[len - 1] & 0x80)) { |
| 877 | + debug_printf("DDD"); |
| 878 | + // Sign propagation in little-endian |
| 879 | + // x = 2 |
| 880 | + // x.to_bytes(1, 'little', True) -> b'\x02' |
| 881 | + // x.to_bytes(4, 'little', True) -> b'\x02\x00\x00\x00' |
| 882 | + // x = -2 |
| 883 | + // x.to_bytes(1, 'little', True) -> b'\xFE' |
| 884 | + // x.to_bytes(4, 'little', True) -> b'\xFE\xFF\xFF\xFF' |
| 885 | + memset(result.buf + len, 0xFF, sizeof(result) - len); |
| 886 | + } |
| 887 | + debug_printf("val: %ld, 0x%X", result.value, result.value); |
| 888 | + mpz_set_from_ll(z, result.value, is_signed); |
| 889 | + return; |
| 890 | + /* |
| 891 | + debug_printf("MPZ"); |
| 892 | + debug_printf("big_endian:%d, is_signed:%d, len:%d", big_endian, is_signed, len) |
| 893 | + debug_printf("buf %X %X %X %X %X %X %X %X", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[len - 1] & 0x80, buf[0] & 0x80) |
860 | 894 | mpz_need_dig(z, (len * 8 + DIG_SIZE - 1) / DIG_SIZE); |
861 | 895 |
|
862 | 896 | mpz_dig_t d = 0; |
863 | 897 | int num_bits = 0; |
864 | 898 | z->neg = 0; |
865 | | - if ((is_signed) && (buf[len - 1] & 0x80)) { |
866 | | - z->neg = 1; |
| 899 | + if (is_signed) { |
| 900 | + debug_printf("is_signed"); |
| 901 | + if (((!big_endian) && (buf[len - 1] & 0x80)) || ((big_endian) && (buf[0] & 0x80))) { |
| 902 | + z->neg = 1; |
| 903 | + debug_printf("NEG"); |
| 904 | + } |
| 905 | + } |
| 906 | + int delta = 1; |
| 907 | + if (big_endian) { |
| 908 | + buf += len - 1; |
| 909 | + delta = -1; |
867 | 910 | } |
868 | 911 | z->len = 0; |
869 | 912 | while (len) { |
@@ -891,6 +934,7 @@ void mpz_set_from_bytes(mpz_t *z, bool big_endian, bool is_signed, size_t len, c |
891 | 934 | z->dig[z->len++] = d & DIG_MASK; |
892 | 935 | } |
893 | 936 | z->len = mpn_remove_trailing_zeros(z->dig, z->dig + z->len); |
| 937 | + */ |
894 | 938 | } |
895 | 939 |
|
896 | 940 | #if 0 |
|
0 commit comments