Simulating int arithmetic with wrap-around

Steve D'Aprano steve+python at pearwood.info
Fri Dec 30 19:30:26 EST 2016


On Sat, 31 Dec 2016 02:14 am, Serhiy Storchaka wrote:

> On 30.12.16 16:47, Steve D'Aprano wrote:
>> Again, assume both operands are in range for an N-bit signed integer.
>> What's a good way to efficiently, or at least not too inefficiently, do
>> the calculations in Python?
> 
> def to_unsigned(bits, x):
>      return x & ((1<<bits)-1)
> 
> def to_signed(bits, x):
>      offset = 1<<(bits-1)
>      return to_unsigned(bits, x + offset) - offset

Thanks.

Are you saying that the best way of doing this is this?

(1) convert signed Python ints to unsigned;

(2) perform operation and bitmask;

(3) convert unsigned back to signed.


Here's an example. I want to multiply 7*3 using a signed 4-bit int, getting
5 as the answer, and 7*4 getting -4 as the answer:


py> N = 4
py> to_signed(N, to_unsigned(N, 7) * to_unsigned(N, 3) & (2**N - 1))
5
py> to_signed(N, to_unsigned(N, 7) * to_unsigned(N, 4) & (2**N - 1))
-4



It works, but I'm glad I won't be doing anything that requires great
speed :-)




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list