Advertisement
aaaaaa123456789

C implementation of StableRandom

Oct 20th, 2017
209
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. struct stable_random_state {
  2.   unsigned shift:  32;
  3.   unsigned carry:   8;
  4.   unsigned current: 8;
  5.   unsigned prev:    8;
  6.   unsigned linear:  8;
  7. };
  8.  
  9. #define STABLE_RANDOM_NEXT_LINEAR(s) ((s) -> linear *= 73, (s) -> linear += 29, (s) -> linear)
  10.  
  11. unsigned char stable_random (struct stable_random_state * state) {
  12.   unsigned p;
  13.   const unsigned char cycle_start_points[] = {1, 2, 4, 8, 13, 17, 23, 26, 29, 58, 0};
  14.   const unsigned char short_cycles[] = {0x72, 0x4f, 0x9f, 0x7b, 0x1a, 0x7b, 0x84, 0xe5, 0x56, 0x8d, 0xb0, 0x32, 0, 0, 1};
  15.   if (!state -> shift) for (p = 0; p < 4; p ++) state -> shift = (state -> shift << 8) | STABLE_RANDOM_NEXT_LINEAR(state);
  16.   state -> shift ^= state -> shift >> 8;
  17.   state -> shift ^= state -> shift << 9;
  18.   state -> shift ^= state -> shift >> 23;
  19.   if (state -> prev || state -> current)
  20.     for (p = 0; p < (sizeof short_cycles - 3); p += 3) {
  21.       if ((state -> prev == short_cycles[p]) && (state -> current == short_cycles[p + 1]) && (state -> carry == short_cycles[p + 2])) {
  22.         state -> prev = short_cycles[p + 3];
  23.         state -> current = short_cycles[p + 4];
  24.         state -> carry = short_cycles[p + 5];
  25.         break;
  26.       }
  27.     }
  28.   else
  29.     for (p = 0; p < (sizeof cycle_start_points - 1); p ++) if (state -> carry == cycle_start_points[p]) {
  30.       state -> carry = cycle_start_points[p + 1];
  31.       if (!state -> carry) {
  32.         state -> prev = *short_cycles;
  33.         state -> current = short_cycles[1];
  34.         state -> carry = short_cycles[2];
  35.         STABLE_RANDOM_NEXT_LINEAR(state);
  36.       }
  37.       break;
  38.     }
  39.   if (state -> carry >= 210) state -> carry -= 210;
  40.   p = state -> carry + state -> prev + state -> current;
  41.   if (!p || (p == 719)) {
  42.     state -> prev = STABLE_RANDOM_NEXT_LINEAR(state);
  43.     state -> carry = STABLE_RANDOM_NEXT_LINEAR(state);
  44.     state -> current = STABLE_RANDOM_NEXT_LINEAR(state);
  45.     if (state -> carry >= 210) state -> carry -= 210;
  46.   }
  47.   p = 210 * state -> prev + state -> carry;
  48.   state -> prev = state -> current;
  49.   state -> current = p & 0xff;
  50.   state -> carry = p >> 8;
  51.   STABLE_RANDOM_NEXT_LINEAR(state);
  52.   p = state -> shift >> ((state -> linear >> 3) & 24);
  53.   switch ((state -> linear >> 4) & 3) {
  54.     case 0:
  55.       return p + state -> current;
  56.     case 1:
  57.       return p ^ state -> current;
  58.     case 2:
  59.       return p - state -> current;
  60.     default:
  61.       return state -> current - p;
  62.   }
  63. }
  64.  
  65. void stable_random_initialize (struct stable_random_state * state, unsigned seed1, unsigned seed2, unsigned initial_mixing_count) {
  66.   // assuming here that unsigned is 32-bit
  67.   state -> shift = seed1;
  68.   1[(unsigned *) state] = seed2;
  69.   while (initial_mixing_count --) stable_random(state);
  70. }
Advertisement
RAW Paste Data Copied
Advertisement