rand.odin 1.4 KB

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