1
0

Xoroshiro64S.cs 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using System.Runtime.CompilerServices;
  2. namespace Content.Shared._RMC14.Random;
  3. // https://github.com/medo64/Medo.ScrambledLinear/blob/main/src/Xoroshiro/Xoroshiro64S.cs
  4. /// <summary>
  5. /// 32-bit random number generator intended for floating point numbers with 64-bit state (xoroshiro64*).
  6. /// </summary>
  7. /// <remarks>http://prng.di.unimi.it/xoroshiro64star.c</remarks>
  8. public record struct Xoroshiro64S
  9. {
  10. /// <summary>
  11. /// Creates a new instance.
  12. /// </summary>
  13. public Xoroshiro64S()
  14. : this(DateTime.UtcNow.Ticks)
  15. {
  16. }
  17. /// <summary>
  18. /// Creates a new instance.
  19. /// </summary>
  20. /// <param name="seed">Seed value.</param>
  21. public Xoroshiro64S(long seed)
  22. {
  23. var sm64 = new SplitMix64(seed);
  24. _s0 = unchecked((UInt32) sm64.Next());
  25. _s1 = unchecked((UInt32) sm64.Next());
  26. }
  27. private UInt32 _s0;
  28. private UInt32 _s1;
  29. /// <summary>
  30. /// Returns the next 32-bit pseudo-random number.
  31. /// </summary>
  32. public int Next()
  33. {
  34. UInt32 s0 = _s0;
  35. UInt32 s1 = _s1;
  36. UInt32 result = unchecked(s0 * (UInt32) 0x9E3779BB);
  37. s1 ^= s0;
  38. _s0 = RotateLeft(s0, 26) ^ s1 ^ (s1 << 9);
  39. _s1 = RotateLeft(s1, 13);
  40. return Math.Abs((int) result);
  41. }
  42. public float NextFloat()
  43. {
  44. return Next() * 4.6566128752458E-10f;
  45. }
  46. public float NextFloat(float min, float max)
  47. {
  48. return NextFloat() * (max - min) + min;
  49. }
  50. private static UInt32 RotateLeft(UInt32 x, int k)
  51. {
  52. return (x << k) | (x >> (32 - k));
  53. }
  54. }