diff options
author | Damien George <damien@micropython.org> | 2021-11-30 00:31:46 +1100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2021-12-21 18:00:05 +1100 |
commit | 2c139bbf4e5724ab253b5b034ce925e04267a9c4 (patch) | |
tree | 68837dc2bebd0350d59b7ab50fbf0c4cab275676 /py/mpz.h | |
parent | 05bea70979232629e059a7453fb7965545113d9f (diff) |
py/mpz: Fix bugs with bitwise of -0 by ensuring all 0's are positive.
This commit makes sure that the value zero is always encoded in an mpz_t as
neg=0 and len=0 (previously it was just len=0).
This invariant is needed for some of the bitwise operations that operate on
negative numbers, because they cannot handle -0. For example
(-((1<<100)-(1<<100)))|1 was being computed as -65535, instead of 1.
Fixes issue #8042.
Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'py/mpz.h')
-rw-r--r-- | py/mpz.h | 3 |
1 files changed, 2 insertions, 1 deletions
@@ -91,6 +91,7 @@ typedef int8_t mpz_dbl_dig_signed_t; #define MPZ_NUM_DIG_FOR_LL ((sizeof(long long) * 8 + MPZ_DIG_SIZE - 1) / MPZ_DIG_SIZE) typedef struct _mpz_t { + // Zero has neg=0, len=0. Negative zero is not allowed. size_t neg : 1; size_t fixed_dig : 1; size_t alloc : (8 * sizeof(size_t) - 2); @@ -119,7 +120,7 @@ static inline bool mpz_is_zero(const mpz_t *z) { return z->len == 0; } static inline bool mpz_is_neg(const mpz_t *z) { - return z->len != 0 && z->neg != 0; + return z->neg != 0; } int mpz_cmp(const mpz_t *lhs, const mpz_t *rhs); |