LCGRandom.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #ifndef CRYINCLUDE_CRYCOMMON_LCGRANDOM_H
  9. #define CRYINCLUDE_CRYCOMMON_LCGRANDOM_H
  10. #pragma once
  11. #include "BaseTypes.h" // uint32, uint64
  12. #include "CryRandomInternal.h" // CryRandom_Internal::BoundedRandom
  13. // A simple Linear Congruential Generator (LCG) of pseudo-randomized numbers.
  14. // NOTE: It should *not* be used for any encryption methods.
  15. //
  16. // We use Microsoft Visual/Quick C/C++ generator's settings (mul 214013, add 2531011)
  17. // (see http://en.wikipedia.org/wiki/Linear_congruential_generator), but our generator
  18. // returns results that are different from Microsoft's:
  19. // Microsoft's version returns 15-bit values (bits 30..16 of the 32-bit state),
  20. // our version returns 32-bit values (bits 47..16 of the 64-bit state).
  21. class CRndGen
  22. {
  23. public:
  24. CRndGen()
  25. {
  26. Seed(5489UL);
  27. }
  28. CRndGen(uint32 seed)
  29. {
  30. Seed(seed);
  31. }
  32. // Initializes the generator using an unsigned 32-bit number.
  33. void Seed(uint32 seed)
  34. {
  35. m_state = (uint64)seed;
  36. }
  37. // Generates a random number in the closed interval [0; max uint32].
  38. uint32 GenerateUint32()
  39. {
  40. m_state = ((uint64)214013) * m_state + ((uint64)2531011);
  41. return (uint32)(m_state >> 16);
  42. }
  43. // Generates a random number in the closed interval [0; max uint64].
  44. uint64 GenerateUint64()
  45. {
  46. const uint32 a = GenerateUint32();
  47. const uint32 b = GenerateUint32();
  48. return ((uint64)b << 32) | (uint64)a;
  49. }
  50. // Generates a random number in the closed interval [0.0f; 1.0f].
  51. float GenerateFloat()
  52. {
  53. return (float)GenerateUint32() * (1.0f / 4294967295.0f);
  54. }
  55. // Ranged function returns random value within the *inclusive* range
  56. // between minValue and maxValue.
  57. // Any orderings work correctly: minValue <= maxValue and
  58. // minValue >= minValue.
  59. template <class T>
  60. T GetRandom(const T minValue, const T maxValue)
  61. {
  62. return CryRandom_Internal::BoundedRandom<CRndGen, T>::Get(*this, minValue, maxValue);
  63. }
  64. // Vector (Vec2, Vec3, Vec4) ranged function returns vector with
  65. // every component within the *inclusive* ranges between minValue.component
  66. // and maxValue.component.
  67. // All orderings work correctly: minValue.component <= maxValue.component and
  68. // minValue.component >= maxValue.component.
  69. template <class T>
  70. T GetRandomComponentwise(const T& minValue, const T& maxValue)
  71. {
  72. return CryRandom_Internal::BoundedRandomComponentwise<CRndGen, T>::Get(*this, minValue, maxValue);
  73. }
  74. // The function returns a random unit vector (Vec2, Vec3, Vec4).
  75. template <class T>
  76. T GetRandomUnitVector()
  77. {
  78. return CryRandom_Internal::GetRandomUnitVector<CRndGen, T>(*this);
  79. }
  80. private:
  81. uint64 m_state;
  82. };
  83. #endif // CRYINCLUDE_CRYCOMMON_LCGRANDOM_H