rand.odin 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. Rand :: struct {
  2. state: u64,
  3. inc: u64,
  4. }
  5. init :: proc(r: ^Rand, seed: u64 = 8675309) {
  6. r.state = 0;
  7. r.inc = (seed << 1) | 1;
  8. _random(r);
  9. r.state += seed;
  10. _random(r);
  11. }
  12. _random :: proc(r: ^Rand) -> u32 {
  13. old_state := r.state;
  14. r.state = old_state * 6364136223846793005 + (r.inc|1);
  15. xor_shifted := u32(((old_state>>18) ~ old_state) >> 27);
  16. rot := u32(old_state >> 59);
  17. return (xor_shifted >> rot) | (xor_shifted << ((-rot) & 31));
  18. }
  19. uint32 :: proc(r: ^Rand) -> u32 { return _random(r); }
  20. uint64 :: proc(r: ^Rand) -> u64 {
  21. a := u64(_random(r));
  22. b := u64(_random(r));
  23. return (a<<32) | b;
  24. }
  25. int31 :: proc(r: ^Rand) -> i32 { return i32(uint32(r) << 1 >> 1); }
  26. int63 :: proc(r: ^Rand) -> i64 { return i64(uint64(r) << 1 >> 1); }
  27. int31_max :: proc(r: ^Rand, n: i32) -> i32 {
  28. if n <= 0 do panic("Invalid argument to int31_max");
  29. if n&(n-1) == 0 {
  30. return int31(r) & (n-1);
  31. }
  32. max := i32((1<<31) - 1 - (1<<31)&u32(n));
  33. v := int31(r);
  34. for v > max {
  35. v = int31(r);
  36. }
  37. return v % n;
  38. }
  39. int63_max :: proc(r: ^Rand, n: i64) -> i64 {
  40. if n <= 0 do panic("Invalid argument to int63_max");
  41. if n&(n-1) == 0 {
  42. return int63(r) & (n-1);
  43. }
  44. max := i64((1<<63) - 1 - (1<<63)&u64(n));
  45. v := int63(r);
  46. for v > max {
  47. v = int63(r);
  48. }
  49. return v % n;
  50. }
  51. float64 :: proc(r: ^Rand) -> f64 { return f64(int63_max(r, 1<<53)) / (1 << 53); }
  52. float32 :: proc(r: ^Rand) -> f32 { return f32(float64(r)); }