Skip to content

Commit e0ac194

Browse files
committed
py: Fix rshift and not of zero/one edge cases in mpz.
Addresses issue adafruit#1027.
1 parent 816a46a commit e0ac194

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

py/mpz.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -871,11 +871,17 @@ void mpz_not_inpl(mpz_t *dest, const mpz_t *z) {
871871
if (dest != z) {
872872
mpz_set(dest, z);
873873
}
874-
if (dest->neg) {
874+
if (dest->len == 0) {
875+
mpz_need_dig(dest, 1);
876+
dest->dig[0] = 1;
877+
dest->len = 1;
878+
dest->neg = 1;
879+
} else if (dest->neg) {
875880
dest->neg = 0;
876881
mpz_dig_t k = 1;
877882
dest->len = mpn_sub(dest->dig, dest->dig, dest->len, &k, 1);
878883
} else {
884+
mpz_need_dig(dest, dest->len + 1);
879885
mpz_dig_t k = 1;
880886
dest->len = mpn_add(dest->dig, dest->dig, dest->len, &k, 1);
881887
dest->neg = 1;
@@ -924,7 +930,14 @@ void mpz_shr_inpl(mpz_t *dest, const mpz_t *lhs, mp_int_t rhs) {
924930
round_up = 1;
925931
}
926932
if (round_up) {
927-
dest->len = mpn_add(dest->dig, dest->dig, dest->len, &round_up, 1);
933+
if (dest->len == 0) {
934+
// dest == 0, so need to add 1 by hand (answer will be -1)
935+
dest->dig[0] = 1;
936+
dest->len = 1;
937+
} else {
938+
// dest > 0, so can use mpn_add to add 1
939+
dest->len = mpn_add(dest->dig, dest->dig, dest->len, &round_up, 1);
940+
}
928941
}
929942
}
930943
}

tests/basics/int_big_zeroone.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# test [0,-0,1,-1] edge cases of bignum
2+
3+
long_zero = (2**64) >> 65
4+
long_neg_zero = -long_zero
5+
long_one = long_zero + 1
6+
long_neg_one = -long_one
7+
8+
cases = [long_zero, long_neg_zero, long_one, long_neg_one]
9+
10+
print(cases)
11+
print([-c for c in cases])
12+
print([~c for c in cases])
13+
print([c >> 1 for c in cases])
14+
print([c << 1 for c in cases])

0 commit comments

Comments
 (0)