PCG32.sf 887 B

12345678910111213141516171819202122232425262728293031323334353637
  1. #!/usr/bin/ruby
  2. # https://rosettacode.org/wiki/Pseudo-random_numbers/PCG32
  3. class PCG32(seed, incr) {
  4. has state
  5. define (
  6. mask32 = (2**32 - 1),
  7. mask64 = (2**64 - 1),
  8. N = 6364136223846793005,
  9. )
  10. method init {
  11. incr = (((incr << 1) | 1) & mask64)
  12. state = (((incr + seed)*N + incr) & mask64)
  13. }
  14. method next_int {
  15. var shift = ((((state >> 18) ^ state) >> 27) & mask32)
  16. var rotate = ((state >> 59) & mask32)
  17. state = ((state*N + incr) & mask64)
  18. ((shift >> rotate) | (shift << (32-rotate))) & mask32
  19. }
  20. method next_float {
  21. self.next_int / (mask32+1) -> float
  22. }
  23. }
  24. say "Seed: 42, Increment: 54, first 5 values:";
  25. var rng = PCG32(seed: 42, incr: 54)
  26. var arr = 5.of { rng.next_int }
  27. assert_eq(arr, [2707161783, 2068313097, 3122475824, 2211639955, 3215226955])
  28. say arr