py/mpz: Complete implementation of mpz_{and,or,xor} for negative args.
For these 3 bitwise operations there are now fast functions for
positive-only arguments, and general functions for arbitrary sign
arguments (the fast functions are the existing implementation).
By default the fast functions are not used (to save space) and instead
the general functions are used for all operations.
Enable MICROPY_OPT_MPZ_BITWISE to use the fast functions for positive
arguments.
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 402e97a..0c46bf3 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -342,6 +342,12 @@
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
#endif
+// Whether to use fast versions of bitwise operations (and, or, xor) when the
+// arguments are both positive. Increases Thumb2 code size by about 250 bytes.
+#ifndef MICROPY_OPT_MPZ_BITWISE
+#define MICROPY_OPT_MPZ_BITWISE (0)
+#endif
+
/*****************************************************************************/
/* Python internal features */
diff --git a/py/mpz.c b/py/mpz.c
index b3f8b15..f02b75c 100644
--- a/py/mpz.c
+++ b/py/mpz.c
@@ -29,9 +29,6 @@
#include "py/mpz.h"
-// this is only needed for mp_not_implemented, which should eventually be removed
-#include "py/runtime.h"
-
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_MPZ
#define DIG_SIZE (MPZ_DIG_SIZE)
@@ -199,6 +196,14 @@
return idig + 1 - oidig;
}
+STATIC mp_uint_t mpn_remove_trailing_zeros(mpz_dig_t *oidig, mpz_dig_t *idig) {
+ for (--idig; idig >= oidig && *idig == 0; --idig) {
+ }
+ return idig + 1 - oidig;
+}
+
+#if MICROPY_OPT_MPZ_BITWISE
+
/* computes i = j & k
returns number of digits in i
assumes enough memory in i; assumes normalised j, k; assumes jlen >= klen (jlen argument not needed)
@@ -211,41 +216,46 @@
*idig = *jdig & *kdig;
}
- // remove trailing zeros
- for (--idig; idig >= oidig && *idig == 0; --idig) {
- }
-
- return idig + 1 - oidig;
+ return mpn_remove_trailing_zeros(oidig, idig);
}
-/* computes i = j & -k = j & (~k + 1)
+#endif
+
+/* i = -((-j) & (-k)) = ~((~j + 1) & (~k + 1)) + 1
+ i = (j & (-k)) = (j & (~k + 1)) = ( j & (~k + 1))
+ i = ((-j) & k) = ((~j + 1) & k) = ((~j + 1) & k )
+ computes general form:
+ i = (im ^ (((j ^ jm) + jc) & ((k ^ km) + kc))) + ic where Xm = Xc == 0 ? 0 : DIG_MASK
returns number of digits in i
- assumes enough memory in i; assumes normalised j, k
+ assumes enough memory in i; assumes normalised j, k; assumes length j >= length k
can have i, j, k pointing to same memory
*/
-STATIC mp_uint_t mpn_and_neg(mpz_dig_t *idig, const mpz_dig_t *jdig, mp_uint_t jlen, const mpz_dig_t *kdig, mp_uint_t klen) {
+STATIC mp_uint_t mpn_and_neg(mpz_dig_t *idig, const mpz_dig_t *jdig, mp_uint_t jlen, const mpz_dig_t *kdig, mp_uint_t klen,
+ mpz_dbl_dig_t carryi, mpz_dbl_dig_t carryj, mpz_dbl_dig_t carryk) {
mpz_dig_t *oidig = idig;
- mpz_dbl_dig_t carry = 1;
+ mpz_dig_t imask = (0 == carryi) ? 0 : DIG_MASK;
+ mpz_dig_t jmask = (0 == carryj) ? 0 : DIG_MASK;
+ mpz_dig_t kmask = (0 == carryk) ? 0 : DIG_MASK;
- for (; jlen > 0 && klen > 0; --jlen, --klen, ++idig, ++jdig, ++kdig) {
- carry += *kdig ^ DIG_MASK;
- *idig = (*jdig & carry) & DIG_MASK;
- carry >>= DIG_SIZE;
+ for (; jlen > 0; ++idig, ++jdig) {
+ carryj += *jdig ^ jmask;
+ carryk += (--klen <= --jlen) ? (*kdig++ ^ kmask) : kmask;
+ carryi += ((carryj & carryk) ^ imask) & DIG_MASK;
+ *idig = carryi & DIG_MASK;
+ carryk >>= DIG_SIZE;
+ carryj >>= DIG_SIZE;
+ carryi >>= DIG_SIZE;
}
- for (; jlen > 0; --jlen, ++idig, ++jdig) {
- carry += DIG_MASK;
- *idig = (*jdig & carry) & DIG_MASK;
- carry >>= DIG_SIZE;
+ if (0 != carryi) {
+ *idig++ = carryi;
}
- // remove trailing zeros
- for (--idig; idig >= oidig && *idig == 0; --idig) {
- }
-
- return idig + 1 - oidig;
+ return mpn_remove_trailing_zeros(oidig, idig);
}
+#if MICROPY_OPT_MPZ_BITWISE
+
/* computes i = j | k
returns number of digits in i
assumes enough memory in i; assumes normalised j, k; assumes jlen >= klen
@@ -267,6 +277,74 @@
return idig - oidig;
}
+#endif
+
+/* i = -((-j) | (-k)) = ~((~j + 1) | (~k + 1)) + 1
+ i = -(j | (-k)) = -(j | (~k + 1)) = ~( j | (~k + 1)) + 1
+ i = -((-j) | k) = -((~j + 1) | k) = ~((~j + 1) | k ) + 1
+ computes general form:
+ i = ~(((j ^ jm) + jc) | ((k ^ km) + kc)) + 1 where Xm = Xc == 0 ? 0 : DIG_MASK
+ returns number of digits in i
+ assumes enough memory in i; assumes normalised j, k; assumes length j >= length k
+ can have i, j, k pointing to same memory
+*/
+
+#if MICROPY_OPT_MPZ_BITWISE
+
+STATIC mp_uint_t mpn_or_neg(mpz_dig_t *idig, const mpz_dig_t *jdig, mp_uint_t jlen, const mpz_dig_t *kdig, mp_uint_t klen,
+ mpz_dbl_dig_t carryj, mpz_dbl_dig_t carryk) {
+ mpz_dig_t *oidig = idig;
+ mpz_dbl_dig_t carryi = 1;
+ mpz_dig_t jmask = (0 == carryj) ? 0 : DIG_MASK;
+ mpz_dig_t kmask = (0 == carryk) ? 0 : DIG_MASK;
+
+ for (; jlen > 0; ++idig, ++jdig) {
+ carryj += *jdig ^ jmask;
+ carryk += (--klen <= --jlen) ? (*kdig++ ^ kmask) : kmask;
+ carryi += ((carryj | carryk) ^ DIG_MASK) & DIG_MASK;
+ *idig = carryi & DIG_MASK;
+ carryk >>= DIG_SIZE;
+ carryj >>= DIG_SIZE;
+ carryi >>= DIG_SIZE;
+ }
+
+ if (0 != carryi) {
+ *idig++ = carryi;
+ }
+
+ return mpn_remove_trailing_zeros(oidig, idig);
+}
+
+#else
+
+STATIC mp_uint_t mpn_or_neg(mpz_dig_t *idig, const mpz_dig_t *jdig, mp_uint_t jlen, const mpz_dig_t *kdig, mp_uint_t klen,
+ mpz_dbl_dig_t carryi, mpz_dbl_dig_t carryj, mpz_dbl_dig_t carryk) {
+ mpz_dig_t *oidig = idig;
+ mpz_dig_t imask = (0 == carryi) ? 0 : DIG_MASK;
+ mpz_dig_t jmask = (0 == carryj) ? 0 : DIG_MASK;
+ mpz_dig_t kmask = (0 == carryk) ? 0 : DIG_MASK;
+
+ for (; jlen > 0; ++idig, ++jdig) {
+ carryj += *jdig ^ jmask;
+ carryk += (--klen <= --jlen) ? (*kdig++ ^ kmask) : kmask;
+ carryi += ((carryj | carryk) ^ imask) & DIG_MASK;
+ *idig = carryi & DIG_MASK;
+ carryk >>= DIG_SIZE;
+ carryj >>= DIG_SIZE;
+ carryi >>= DIG_SIZE;
+ }
+
+ if (0 != carryi) {
+ *idig++ = carryi;
+ }
+
+ return mpn_remove_trailing_zeros(oidig, idig);
+}
+
+#endif
+
+#if MICROPY_OPT_MPZ_BITWISE
+
/* computes i = j ^ k
returns number of digits in i
assumes enough memory in i; assumes normalised j, k; assumes jlen >= klen
@@ -285,11 +363,39 @@
*idig = *jdig;
}
- // remove trailing zeros
- for (--idig; idig >= oidig && *idig == 0; --idig) {
+ return mpn_remove_trailing_zeros(oidig, idig);
+}
+
+#endif
+
+/* i = (-j) ^ (-k) = ~(j - 1) ^ ~(k - 1) = (j - 1) ^ (k - 1)
+ i = -(j ^ (-k)) = -(j ^ ~(k - 1)) = ~(j ^ ~(k - 1)) + 1 = (j ^ (k - 1)) + 1
+ i = -((-j) ^ k) = -(~(j - 1) ^ k) = ~(~(j - 1) ^ k) + 1 = ((j - 1) ^ k) + 1
+ computes general form:
+ i = ((j - 1 + jc) ^ (k - 1 + kc)) + ic
+ returns number of digits in i
+ assumes enough memory in i; assumes normalised j, k; assumes length j >= length k
+ can have i, j, k pointing to same memory
+*/
+STATIC mp_uint_t mpn_xor_neg(mpz_dig_t *idig, const mpz_dig_t *jdig, mp_uint_t jlen, const mpz_dig_t *kdig, mp_uint_t klen,
+ mpz_dbl_dig_t carryi, mpz_dbl_dig_t carryj, mpz_dbl_dig_t carryk) {
+ mpz_dig_t *oidig = idig;
+
+ for (; jlen > 0; ++idig, ++jdig) {
+ carryj += *jdig + DIG_MASK;
+ carryk += (--klen <= --jlen) ? (*kdig++ + DIG_MASK) : DIG_MASK;
+ carryi += (carryj ^ carryk) & DIG_MASK;
+ *idig = carryi & DIG_MASK;
+ carryk >>= DIG_SIZE;
+ carryj >>= DIG_SIZE;
+ carryi >>= DIG_SIZE;
}
- return idig + 1 - oidig;
+ if (0 != carryi) {
+ *idig++ = carryi;
+ }
+
+ return mpn_remove_trailing_zeros(oidig, idig);
}
/* computes i = i * d1 + d2
@@ -1097,81 +1203,106 @@
can have dest, lhs, rhs the same
*/
void mpz_and_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
- if (lhs->neg == rhs->neg) {
- if (lhs->neg == 0) {
- // make sure lhs has the most digits
- if (lhs->len < rhs->len) {
- const mpz_t *temp = lhs;
- lhs = rhs;
- rhs = temp;
- }
- // do the and'ing
- mpz_need_dig(dest, rhs->len);
- dest->len = mpn_and(dest->dig, lhs->dig, rhs->dig, rhs->len);
- dest->neg = 0;
- } else {
- // TODO both args are negative
- mp_not_implemented("bignum and with negative args");
- }
- } else {
- // args have different sign
- // make sure lhs is the positive arg
- if (rhs->neg == 0) {
- const mpz_t *temp = lhs;
- lhs = rhs;
- rhs = temp;
- }
- mpz_need_dig(dest, lhs->len + 1);
- dest->len = mpn_and_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
- assert(dest->len <= dest->alloc);
- dest->neg = 0;
+ // make sure lhs has the most digits
+ if (lhs->len < rhs->len) {
+ const mpz_t *temp = lhs;
+ lhs = rhs;
+ rhs = temp;
}
+
+ #if MICROPY_OPT_MPZ_BITWISE
+
+ if ((0 == lhs->neg) && (0 == rhs->neg)) {
+ mpz_need_dig(dest, lhs->len);
+ dest->len = mpn_and(dest->dig, lhs->dig, rhs->dig, rhs->len);
+ dest->neg = 0;
+ } else {
+ mpz_need_dig(dest, lhs->len + 1);
+ dest->len = mpn_and_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len,
+ lhs->neg == rhs->neg, 0 != lhs->neg, 0 != rhs->neg);
+ dest->neg = lhs->neg & rhs->neg;
+ }
+
+ #else
+
+ mpz_need_dig(dest, lhs->len + (lhs->neg || rhs->neg));
+ dest->len = mpn_and_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len,
+ (lhs->neg == rhs->neg) ? lhs->neg : 0, lhs->neg, rhs->neg);
+ dest->neg = lhs->neg & rhs->neg;
+
+ #endif
}
/* computes dest = lhs | rhs
can have dest, lhs, rhs the same
*/
void mpz_or_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
- if (mpn_cmp(lhs->dig, lhs->len, rhs->dig, rhs->len) < 0) {
+ // make sure lhs has the most digits
+ if (lhs->len < rhs->len) {
const mpz_t *temp = lhs;
lhs = rhs;
rhs = temp;
}
- if (lhs->neg == rhs->neg) {
+ #if MICROPY_OPT_MPZ_BITWISE
+
+ if ((0 == lhs->neg) && (0 == rhs->neg)) {
mpz_need_dig(dest, lhs->len);
dest->len = mpn_or(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
+ dest->neg = 0;
} else {
- mpz_need_dig(dest, lhs->len);
- // TODO
- mp_not_implemented("bignum or with negative args");
-// dest->len = mpn_or_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
+ mpz_need_dig(dest, lhs->len + 1);
+ dest->len = mpn_or_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len,
+ 0 != lhs->neg, 0 != rhs->neg);
+ dest->neg = 1;
}
- dest->neg = lhs->neg;
+ #else
+
+ mpz_need_dig(dest, lhs->len + (lhs->neg || rhs->neg));
+ dest->len = mpn_or_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len,
+ (lhs->neg || rhs->neg), lhs->neg, rhs->neg);
+ dest->neg = lhs->neg | rhs->neg;
+
+ #endif
}
/* computes dest = lhs ^ rhs
can have dest, lhs, rhs the same
*/
void mpz_xor_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
- if (mpn_cmp(lhs->dig, lhs->len, rhs->dig, rhs->len) < 0) {
+ // make sure lhs has the most digits
+ if (lhs->len < rhs->len) {
const mpz_t *temp = lhs;
lhs = rhs;
rhs = temp;
}
+ #if MICROPY_OPT_MPZ_BITWISE
+
if (lhs->neg == rhs->neg) {
mpz_need_dig(dest, lhs->len);
- dest->len = mpn_xor(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
+ if (lhs->neg == 0) {
+ dest->len = mpn_xor(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
+ } else {
+ dest->len = mpn_xor_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len, 0, 0, 0);
+ }
+ dest->neg = 0;
} else {
- mpz_need_dig(dest, lhs->len);
- // TODO
- mp_not_implemented("bignum xor with negative args");
-// dest->len = mpn_xor_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len);
+ mpz_need_dig(dest, lhs->len + 1);
+ dest->len = mpn_xor_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len, 1,
+ 0 == lhs->neg, 0 == rhs->neg);
+ dest->neg = 1;
}
- dest->neg = 0;
+ #else
+
+ mpz_need_dig(dest, lhs->len + (lhs->neg || rhs->neg));
+ dest->len = mpn_xor_neg(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len,
+ (lhs->neg != rhs->neg), 0 == lhs->neg, 0 == rhs->neg);
+ dest->neg = lhs->neg ^ rhs->neg;
+
+ #endif
}
/* computes dest = lhs * rhs
diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h
index eaf1da7..cea8a3e 100644
--- a/stmhal/mpconfigport.h
+++ b/stmhal/mpconfigport.h
@@ -46,6 +46,7 @@
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
#define MICROPY_OPT_COMPUTED_GOTO (1)
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
+#define MICROPY_OPT_MPZ_BITWISE (1)
// fatfs configuration used in ffconf.h
#define MICROPY_FATFS_ENABLE_LFN (1)
diff --git a/tests/basics/int_big_and.py b/tests/basics/int_big_and.py
index 2dabe80..b3bba37 100644
--- a/tests/basics/int_big_and.py
+++ b/tests/basics/int_big_and.py
@@ -26,3 +26,120 @@
print((-a) & 0xffffffffffffffffffffffffffffffff)
print((-a) & 2)
print((-(1 << 70)) & 2)
+
+# test negative on lhs and rhs
+mpz = 1 << 70
+a = 123456789012345678901234567890
+print(-1 & (-a))
+print(-2 & (-a))
+print(-2345678901234567890123456789 & (-a))
+print((-a) & (-a))
+print((-a) & (-0xffffffff))
+print((-a) & (-0xffffffffffffffffffffffffffffffff))
+print((-1) & (-0xffffffffffffffffffffffffffffffff))
+print((-a) & (-2))
+print((-mpz) & (-2))
+
+# test + +
+
+print( 97989513389222316022151446562729620153292831887555425160965597396
+ & 23716683549865351578586448630079789776107310103486834795830390982)
+
+print( 53817081128841898634258263553430908085326601592682411889506742059
+ & 37042558948907407488299113387826240429667200950043601129661240876)
+
+print( 26167512042587370698808974207700979337713004510730289760097826496
+ & 98456276326770292376138852628141531773120376436197321310863125849)
+
+print( 21085380307304977067262070503651827226504797285572981274069266136
+ & 15928222825828272388778130358888206480162413547887287646273147570)
+
+print( 40827393422334167255488276244226338235131323044408420081160772273
+ & 63815443187857978125545555033672525708399848575557475462799643340)
+
+print( 5181013159871685724135944379095645225188360725917119022722046448
+ & 59734090450462480092384049604830976376887859531148103803093112493)
+
+print( 283894311
+ & 86526825689187217371383854139783231460931720533100376593106943447)
+
+print( 40019818573920230246248826511203818792007462193311949166285967147
+ & 9487909752)
+
+# test - +
+
+print( -97989513389222316022151446562729620153292831887555425160965597396
+ & 23716683549865351578586448630079789776107310103486834795830390982)
+
+print( -53817081128841898634258263553430908085326601592682411889506742059
+ & 37042558948907407488299113387826240429667200950043601129661240876)
+
+print( -26167512042587370698808974207700979337713004510730289760097826496
+ & 98456276326770292376138852628141531773120376436197321310863125849)
+
+print( -21085380307304977067262070503651827226504797285572981274069266136
+ & 15928222825828272388778130358888206480162413547887287646273147570)
+
+print( -40827393422334167255488276244226338235131323044408420081160772273
+ & 63815443187857978125545555033672525708399848575557475462799643340)
+
+print( -5181013159871685724135944379095645225188360725917119022722046448
+ & 59734090450462480092384049604830976376887859531148103803093112493)
+
+print( -283894311
+ & 86526825689187217371383854139783231460931720533100376593106943447)
+
+print( -40019818573920230246248826511203818792007462193311949166285967147
+ & 9487909752)
+
+# test + -
+
+print( 97989513389222316022151446562729620153292831887555425160965597396
+ & -23716683549865351578586448630079789776107310103486834795830390982)
+
+print( 53817081128841898634258263553430908085326601592682411889506742059
+ & -37042558948907407488299113387826240429667200950043601129661240876)
+
+print( 26167512042587370698808974207700979337713004510730289760097826496
+ & -98456276326770292376138852628141531773120376436197321310863125849)
+
+print( 21085380307304977067262070503651827226504797285572981274069266136
+ & -15928222825828272388778130358888206480162413547887287646273147570)
+
+print( 40827393422334167255488276244226338235131323044408420081160772273
+ & -63815443187857978125545555033672525708399848575557475462799643340)
+
+print( 5181013159871685724135944379095645225188360725917119022722046448
+ & -59734090450462480092384049604830976376887859531148103803093112493)
+
+print( 283894311
+ & -86526825689187217371383854139783231460931720533100376593106943447)
+
+print( 40019818573920230246248826511203818792007462193311949166285967147
+ & -9487909752)
+
+# test - -
+
+print( -97989513389222316022151446562729620153292831887555425160965597396
+ & -23716683549865351578586448630079789776107310103486834795830390982)
+
+print( -53817081128841898634258263553430908085326601592682411889506742059
+ & -37042558948907407488299113387826240429667200950043601129661240876)
+
+print( -26167512042587370698808974207700979337713004510730289760097826496
+ & -98456276326770292376138852628141531773120376436197321310863125849)
+
+print( -21085380307304977067262070503651827226504797285572981274069266136
+ & -15928222825828272388778130358888206480162413547887287646273147570)
+
+print( -40827393422334167255488276244226338235131323044408420081160772273
+ & -63815443187857978125545555033672525708399848575557475462799643340)
+
+print( -5181013159871685724135944379095645225188360725917119022722046448
+ & -59734090450462480092384049604830976376887859531148103803093112493)
+
+print( -283894311
+ & -86526825689187217371383854139783231460931720533100376593106943447)
+
+print( -40019818573920230246248826511203818792007462193311949166285967147
+ & -9487909752)
diff --git a/tests/basics/int_big_or.py b/tests/basics/int_big_or.py
index a279ce7..0defd98 100644
--- a/tests/basics/int_big_or.py
+++ b/tests/basics/int_big_or.py
@@ -2,3 +2,143 @@
a = 0xfffffffffffffffffffffffffffff
print(a | (1 << 200))
+
+
+# test + +
+
+print(0 | (1 << 80))
+print((1 << 80) | (1 << 80))
+print((1 << 80) | 0)
+
+a = 0xfffffffffffffffffffffffffffff
+print(a | (1 << 100))
+print(a | (1 << 200))
+print(a | a == 0)
+print(bool(a | a))
+
+print( 97989513389222316022151446562729620153292831887555425160965597396
+ | 23716683549865351578586448630079789776107310103486834795830390982)
+
+print( 53817081128841898634258263553430908085326601592682411889506742059
+ | 37042558948907407488299113387826240429667200950043601129661240876)
+
+print( 26167512042587370698808974207700979337713004510730289760097826496
+ | 98456276326770292376138852628141531773120376436197321310863125849)
+
+print( 21085380307304977067262070503651827226504797285572981274069266136
+ | 15928222825828272388778130358888206480162413547887287646273147570)
+
+print( 40827393422334167255488276244226338235131323044408420081160772273
+ | 63815443187857978125545555033672525708399848575557475462799643340)
+
+print( 5181013159871685724135944379095645225188360725917119022722046448
+ | 59734090450462480092384049604830976376887859531148103803093112493)
+
+print( 283894311
+ | 86526825689187217371383854139783231460931720533100376593106943447)
+
+print( 40019818573920230246248826511203818792007462193311949166285967147
+ | 9487909752)
+
+# test - +
+
+print((-1 << 80) | (1 << 80))
+print((-1 << 80) | 0)
+
+print((-a) | (1 << 100))
+print((-a) | (1 << 200))
+print((-a) | a == 0)
+print(bool((-a) | a))
+
+print( -97989513389222316022151446562729620153292831887555425160965597396
+ | 23716683549865351578586448630079789776107310103486834795830390982)
+
+print( -53817081128841898634258263553430908085326601592682411889506742059
+ | 37042558948907407488299113387826240429667200950043601129661240876)
+
+print( -26167512042587370698808974207700979337713004510730289760097826496
+ | 98456276326770292376138852628141531773120376436197321310863125849)
+
+print( -21085380307304977067262070503651827226504797285572981274069266136
+ | 15928222825828272388778130358888206480162413547887287646273147570)
+
+print( -40827393422334167255488276244226338235131323044408420081160772273
+ | 63815443187857978125545555033672525708399848575557475462799643340)
+
+print( -5181013159871685724135944379095645225188360725917119022722046448
+ | 59734090450462480092384049604830976376887859531148103803093112493)
+
+print( -283894311
+ | 86526825689187217371383854139783231460931720533100376593106943447)
+
+print( -40019818573920230246248826511203818792007462193311949166285967147
+ | 9487909752)
+
+# test + -
+
+print(0 | (-1 << 80))
+print((1 << 80) | (-1 << 80))
+
+print(a | (-1 << 100))
+print(a | (-1 << 200))
+print(a | (-a) == 0)
+print(bool(a | (-a)))
+
+print( 97989513389222316022151446562729620153292831887555425160965597396
+ | -23716683549865351578586448630079789776107310103486834795830390982)
+
+print( 53817081128841898634258263553430908085326601592682411889506742059
+ | -37042558948907407488299113387826240429667200950043601129661240876)
+
+print( 26167512042587370698808974207700979337713004510730289760097826496
+ | -98456276326770292376138852628141531773120376436197321310863125849)
+
+print( 21085380307304977067262070503651827226504797285572981274069266136
+ | -15928222825828272388778130358888206480162413547887287646273147570)
+
+print( 40827393422334167255488276244226338235131323044408420081160772273
+ | -63815443187857978125545555033672525708399848575557475462799643340)
+
+print( 5181013159871685724135944379095645225188360725917119022722046448
+ | -59734090450462480092384049604830976376887859531148103803093112493)
+
+print( 283894311
+ | -86526825689187217371383854139783231460931720533100376593106943447)
+
+print( 40019818573920230246248826511203818792007462193311949166285967147
+ | -9487909752)
+
+# test - -
+
+print((-1 << 80) | (-1 << 80))
+
+print((-a) | (-1 << 100))
+print((-a) | (-1 << 200))
+print((-a) | (-a) == 0)
+print(bool((-a) | (-a)))
+
+print( -97989513389222316022151446562729620153292831887555425160965597396
+ | -23716683549865351578586448630079789776107310103486834795830390982)
+
+print( -53817081128841898634258263553430908085326601592682411889506742059
+ | -37042558948907407488299113387826240429667200950043601129661240876)
+
+print( -26167512042587370698808974207700979337713004510730289760097826496
+ | -98456276326770292376138852628141531773120376436197321310863125849)
+
+print( -21085380307304977067262070503651827226504797285572981274069266136
+ | -15928222825828272388778130358888206480162413547887287646273147570)
+
+print( -40827393422334167255488276244226338235131323044408420081160772273
+ | -63815443187857978125545555033672525708399848575557475462799643340)
+
+print( -5181013159871685724135944379095645225188360725917119022722046448
+ | -59734090450462480092384049604830976376887859531148103803093112493)
+
+print( -283894311
+ | -86526825689187217371383854139783231460931720533100376593106943447)
+
+print( -40019818573920230246248826511203818792007462193311949166285967147
+ | -9487909752)
+
+
diff --git a/tests/basics/int_big_xor.py b/tests/basics/int_big_xor.py
index 1c6278b..f14a763 100644
--- a/tests/basics/int_big_xor.py
+++ b/tests/basics/int_big_xor.py
@@ -1,3 +1,6 @@
+
+# test + +
+
print(0 ^ (1 << 80))
print((1 << 80) ^ (1 << 80))
print((1 << 80) ^ 0)
@@ -7,3 +10,129 @@
print(a ^ (1 << 200))
print(a ^ a == 0)
print(bool(a ^ a))
+
+print( 97989513389222316022151446562729620153292831887555425160965597396
+ ^ 23716683549865351578586448630079789776107310103486834795830390982)
+
+print( 53817081128841898634258263553430908085326601592682411889506742059
+ ^ 37042558948907407488299113387826240429667200950043601129661240876)
+
+print( 26167512042587370698808974207700979337713004510730289760097826496
+ ^ 98456276326770292376138852628141531773120376436197321310863125849)
+
+print( 21085380307304977067262070503651827226504797285572981274069266136
+ ^ 15928222825828272388778130358888206480162413547887287646273147570)
+
+print( 40827393422334167255488276244226338235131323044408420081160772273
+ ^ 63815443187857978125545555033672525708399848575557475462799643340)
+
+print( 5181013159871685724135944379095645225188360725917119022722046448
+ ^ 59734090450462480092384049604830976376887859531148103803093112493)
+
+print( 283894311
+ ^ 86526825689187217371383854139783231460931720533100376593106943447)
+
+print( 40019818573920230246248826511203818792007462193311949166285967147
+ ^ 9487909752)
+
+# test - +
+
+print((-1 << 80) ^ (1 << 80))
+print((-1 << 80) ^ 0)
+
+print((-a) ^ (1 << 100))
+print((-a) ^ (1 << 200))
+print((-a) ^ a == 0)
+print(bool((-a) ^ a))
+
+print( -97989513389222316022151446562729620153292831887555425160965597396
+ ^ 23716683549865351578586448630079789776107310103486834795830390982)
+
+print( -53817081128841898634258263553430908085326601592682411889506742059
+ ^ 37042558948907407488299113387826240429667200950043601129661240876)
+
+print( -26167512042587370698808974207700979337713004510730289760097826496
+ ^ 98456276326770292376138852628141531773120376436197321310863125849)
+
+print( -21085380307304977067262070503651827226504797285572981274069266136
+ ^ 15928222825828272388778130358888206480162413547887287646273147570)
+
+print( -40827393422334167255488276244226338235131323044408420081160772273
+ ^ 63815443187857978125545555033672525708399848575557475462799643340)
+
+print( -5181013159871685724135944379095645225188360725917119022722046448
+ ^ 59734090450462480092384049604830976376887859531148103803093112493)
+
+print( -283894311
+ ^ 86526825689187217371383854139783231460931720533100376593106943447)
+
+print( -40019818573920230246248826511203818792007462193311949166285967147
+ ^ 9487909752)
+
+# test + -
+
+print(0 ^ (-1 << 80))
+print((1 << 80) ^ (-1 << 80))
+
+print(a ^ (-1 << 100))
+print(a ^ (-1 << 200))
+print(a ^ (-a) == 0)
+print(bool(a ^ (-a)))
+
+print( 97989513389222316022151446562729620153292831887555425160965597396
+ ^ -23716683549865351578586448630079789776107310103486834795830390982)
+
+print( 53817081128841898634258263553430908085326601592682411889506742059
+ ^ -37042558948907407488299113387826240429667200950043601129661240876)
+
+print( 26167512042587370698808974207700979337713004510730289760097826496
+ ^ -98456276326770292376138852628141531773120376436197321310863125849)
+
+print( 21085380307304977067262070503651827226504797285572981274069266136
+ ^ -15928222825828272388778130358888206480162413547887287646273147570)
+
+print( 40827393422334167255488276244226338235131323044408420081160772273
+ ^ -63815443187857978125545555033672525708399848575557475462799643340)
+
+print( 5181013159871685724135944379095645225188360725917119022722046448
+ ^ -59734090450462480092384049604830976376887859531148103803093112493)
+
+print( 283894311
+ ^ -86526825689187217371383854139783231460931720533100376593106943447)
+
+print( 40019818573920230246248826511203818792007462193311949166285967147
+ ^ -9487909752)
+
+# test - -
+
+print((-1 << 80) ^ (-1 << 80))
+
+print((-a) ^ (-1 << 100))
+print((-a) ^ (-1 << 200))
+print((-a) ^ (-a) == 0)
+print(bool((-a) ^ (-a)))
+
+print( -97989513389222316022151446562729620153292831887555425160965597396
+ ^ -23716683549865351578586448630079789776107310103486834795830390982)
+
+print( -53817081128841898634258263553430908085326601592682411889506742059
+ ^ -37042558948907407488299113387826240429667200950043601129661240876)
+
+print( -26167512042587370698808974207700979337713004510730289760097826496
+ ^ -98456276326770292376138852628141531773120376436197321310863125849)
+
+print( -21085380307304977067262070503651827226504797285572981274069266136
+ ^ -15928222825828272388778130358888206480162413547887287646273147570)
+
+print( -40827393422334167255488276244226338235131323044408420081160772273
+ ^ -63815443187857978125545555033672525708399848575557475462799643340)
+
+print( -5181013159871685724135944379095645225188360725917119022722046448
+ ^ -59734090450462480092384049604830976376887859531148103803093112493)
+
+print( -283894311
+ ^ -86526825689187217371383854139783231460931720533100376593106943447)
+
+print( -40019818573920230246248826511203818792007462193311949166285967147
+ ^ -9487909752)
+
diff --git a/tests/misc/non_compliant.py b/tests/misc/non_compliant.py
index 9c55ac2..c760c2a 100644
--- a/tests/misc/non_compliant.py
+++ b/tests/misc/non_compliant.py
@@ -70,22 +70,3 @@
except NotImplementedError:
print('NotImplementedError')
-mpz = 1 << 70
-
-# mpz and with both args negative
-try:
- -mpz & -2
-except NotImplementedError:
- print('NotImplementedError')
-
-# mpz or with args opposite sign
-try:
- -mpz | 2
-except NotImplementedError:
- print('NotImplementedError')
-
-# mpz xor with args opposite sign
-try:
- -mpz ^ 2
-except NotImplementedError:
- print('NotImplementedError')
diff --git a/tests/misc/non_compliant.py.exp b/tests/misc/non_compliant.py.exp
index 5937ccb..28b1470 100644
--- a/tests/misc/non_compliant.py.exp
+++ b/tests/misc/non_compliant.py.exp
@@ -9,6 +9,3 @@
NotImplementedError
NotImplementedError
NotImplementedError
-NotImplementedError
-NotImplementedError
-NotImplementedError