vendredi 16 juillet 2021

Compute modulo 2^32 - 1 operation without division

I was reading about CMWC PRNG and found the claim that it is possible to compute a mod (2^32 - 1) without using slow modulo operation. My question is very similar to Is there any easy way to do modulus of 2^32 - 1 operation? but I found only while-loop-based solutions for the general case of large a that may be even larger than 2^64.

I tried to understand how the authors of CMWC implemented their algorithm (page 9) without loops and extracted crucial piece of it. I wrote it in python pseudocode to make it more clear when modulo division by 2^32 happens as C++ implementation hides it behind unsigned overflow. So the following fragment of code

c = (a // b) % b
x = (a + c) % b
if (x < c):
    x = (x + 1)
    c = (c + 1)

is equivalent to

x = a % (b - 1)
c = a // (b - 1)

It works for b = 2^32 and 0 <= a < 2^64 when a % (2^32 - 1) != 0 (such a seems to be never used in this PRNG). Actually, this pseudocode works correctly even in the general case of b > 3, 0 <= a < b^2, a % (b - 1) != 0.

So my question is how to explain that the pseudocode above works at all? I don't understand the reasoning behind it and wondering how I could come up with this simplification of division myself.




Aucun commentaire:

Enregistrer un commentaire