gmpy
gmpy copied to clipboard
Incorrect values when accessing sign bits through slicing
Hi, I encountered a situation that I think is probably a bug.
Accessing the sign bits of negative mpz
and xmpz
numbers gives different results when the access is done with simple indexing and when the access is done through slicing:
In [1]: from gmpy2 import mpz
In [2]: a = mpz(-1)
In [3]: a[4]
Out[3]: 1
In [5]: a[4:5]
Out[5]: mpz(0)
Expected result: slices of sign bits should give 11..1
for negative integers instead of 00..0
.
Thank you in advance for your help!
Valentin
As a workaround I'm using bit_mask and bit shift:
from gmpy2 import mpz, bit_mask
# one bit
(a >> 4) & 1
# multi bit
(a >> 4) & bit_mask(3)
This is an interesting issue. I need to think about the best solution.
Let's assume a is always a negative 'mpz'.
What should a[2:] return? Without a given stop value, this will effectively lock up a system, and eventually crash the interpreter, while it tries to return an infinite number. I think maintaining the existing behavior is best when no stop value is given.
If we assume that a stop value is present, the change looks easy on Python 3.6.1 and later. (New C-API functions introduced.) I need to see if there is a reasonable fix for older versions of Python.
That's interesting, I hadn't thought about the unbounded slices! I wonder if unbounded slices are really necessary though? As a user it seems a bit counter-intuitive to me that a[0:]
and a
are not the same
In [21]: a = xmpz(-2)
In [22]: a[0:]
Out[22]: mpz(2)
Maybe unbounded slices in getter expressions should be forbidden for consistency? A user can use bit_length() to be explicit if this is really what they want.
But i do see why unbounded slices could be useful on the LHS, looks like I found another edge case though, I'll open a second issue :)
Edit: and here's the issue report #342