Random.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #pragma once
  2. #include "Types.h"
  3. //-----------------------------------------------------------------------------
  4. // Xorshift RNG based on code by George Marsaglia
  5. // http://en.wikipedia.org/wiki/Xorshift
  6. struct Rand
  7. {
  8. uint32_t x;
  9. uint32_t y;
  10. uint32_t z;
  11. uint32_t w;
  12. Rand()
  13. {
  14. reseed(uint32_t(0));
  15. }
  16. Rand( uint32_t seed )
  17. {
  18. reseed(seed);
  19. }
  20. void reseed ( uint32_t seed )
  21. {
  22. x = 0x498b3bc5 ^ seed;
  23. y = 0;
  24. z = 0;
  25. w = 0;
  26. for(int i = 0; i < 10; i++) mix();
  27. }
  28. void reseed ( uint64_t seed )
  29. {
  30. x = 0x498b3bc5 ^ (uint32_t)(seed >> 0);
  31. y = 0x5a05089a ^ (uint32_t)(seed >> 32);
  32. z = 0;
  33. w = 0;
  34. for(int i = 0; i < 10; i++) mix();
  35. }
  36. //-----------------------------------------------------------------------------
  37. void mix ( void )
  38. {
  39. uint32_t t = x ^ (x << 11);
  40. x = y; y = z; z = w;
  41. w = w ^ (w >> 19) ^ t ^ (t >> 8);
  42. }
  43. uint32_t rand_u32 ( void )
  44. {
  45. mix();
  46. return x;
  47. }
  48. uint64_t rand_u64 ( void )
  49. {
  50. mix();
  51. uint64_t a = x;
  52. uint64_t b = y;
  53. return (a << 32) | b;
  54. }
  55. void rand_p ( void * blob, int bytes )
  56. {
  57. uint32_t * blocks = reinterpret_cast<uint32_t*>(blob);
  58. while(bytes >= 4)
  59. {
  60. blocks[0] = rand_u32();
  61. blocks++;
  62. bytes -= 4;
  63. }
  64. uint8_t * tail = reinterpret_cast<uint8_t*>(blocks);
  65. for(int i = 0; i < bytes; i++)
  66. {
  67. tail[i] = (uint8_t)rand_u32();
  68. }
  69. }
  70. };
  71. //-----------------------------------------------------------------------------
  72. extern Rand g_rand1;
  73. inline uint32_t rand_u32 ( void ) { return g_rand1.rand_u32(); }
  74. inline uint64_t rand_u64 ( void ) { return g_rand1.rand_u64(); }
  75. inline void rand_p ( void * blob, int bytes )
  76. {
  77. uint32_t * blocks = (uint32_t*)blob;
  78. while(bytes >= 4)
  79. {
  80. *blocks++ = rand_u32();
  81. bytes -= 4;
  82. }
  83. uint8_t * tail = (uint8_t*)blocks;
  84. for(int i = 0; i < bytes; i++)
  85. {
  86. tail[i] = (uint8_t)rand_u32();
  87. }
  88. }
  89. //-----------------------------------------------------------------------------