gavzik

Untitled

Oct 21st, 2024
16
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4.  
  5. /* http://marc-b-reynolds.github.io/math/2017/09/18/ModInverse.html */
  6. static uint32_t modinv(uint32_t a)
  7. {
  8.     uint32_t x;
  9.     x = a;      //  3 bits
  10.     x *= 2 - a*x;   //  6
  11.     x *= 2 - a*x;   // 12
  12.     x *= 2 - a*x;   // 24
  13.     x *= 2 - a*x;   // 48 / retaining bottom 32
  14.     return x;
  15. }
  16.  
  17. /* http://number-none.com/blow/blog/programming/2016/07/08/fabian-on-lcg-fast-forward.html */
  18. uint32_t skip(uint32_t x, uint32_t a, uint32_t c, unsigned n)
  19. {
  20.     while (n) {
  21.             if (n & 1)
  22.                 x = a * x + c;
  23.         c *= a + 1;
  24.         a *= a;
  25.         n >>= 1;
  26.     }
  27.     return x;
  28. }
  29.  
  30. int main(int argc, char **argv)
  31. {
  32.     srandom(time(NULL));
  33.     unsigned i, s = 1, a = random() | 1UL, c =  random() | 1UL;
  34.  
  35.     /* move forward one step at a time */
  36.     for (i = 0; i < 100; i++)
  37.         s = s * a + c;
  38.     printf("%08x\n", s);
  39.     /* skip forwaward */
  40.     printf("%08x\n", skip(1, a, c, 100));
  41.     /* you could loop through the full LCG cycle */
  42.     printf("%08x\n", skip(s, a, c, -100));
  43.     /* or inverse of LCG is still LCG */
  44.     a = modinv(a);
  45.     c = -c * a;
  46.     /* skip backward */
  47.     printf("%08x\n", skip(s, a, c, 100));
  48.     /* move backward one step at a time */
  49.     for (i = 0; i < 100; i++)
  50.         s = s * a + c;
  51.     printf("%08x\n", s);
  52. }
Add Comment
Please, Sign In to add comment