OpenShot Audio Library | OpenShotAudio  0.6.0
juce_Random.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2022 - Raw Material Software Limited
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 Random::Random (int64 seedValue) noexcept : seed (seedValue)
27 {
28 }
29 
30 Random::Random() : seed (1)
31 {
33 }
34 
35 void Random::setSeed (const int64 newSeed) noexcept
36 {
37  if (this == &getSystemRandom())
38  {
39  // Resetting the system Random risks messing up
40  // JUCE's internal state. If you need a predictable
41  // stream of random numbers you should use a local
42  // Random object.
43  jassertfalse;
44  return;
45  }
46 
47  seed = newSeed;
48 }
49 
50 void Random::combineSeed (const int64 seedValue) noexcept
51 {
52  seed ^= nextInt64() ^ seedValue;
53 }
54 
56 {
57  static std::atomic<int64> globalSeed { 0 };
58 
59  combineSeed (globalSeed ^ (int64) (pointer_sized_int) this);
64  globalSeed ^= seed;
65 }
66 
68 {
69  static Random sysRand;
70  return sysRand;
71 }
72 
73 //==============================================================================
74 int Random::nextInt() noexcept
75 {
76  seed = (int64) (((((uint64) seed) * 0x5deece66dLL) + 11) & 0xffffffffffffLL);
77 
78  return (int) (seed >> 16);
79 }
80 
81 int Random::nextInt (const int maxValue) noexcept
82 {
83  jassert (maxValue > 0);
84  return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32);
85 }
86 
87 int Random::nextInt (Range<int> range) noexcept
88 {
89  return range.getStart() + nextInt (range.getLength());
90 }
91 
92 int64 Random::nextInt64() noexcept
93 {
94  return (int64) ((((uint64) (unsigned int) nextInt()) << 32) | (uint64) (unsigned int) nextInt());
95 }
96 
97 bool Random::nextBool() noexcept
98 {
99  return (nextInt() & 0x40000000) != 0;
100 }
101 
102 float Random::nextFloat() noexcept
103 {
104  auto result = static_cast<float> (static_cast<uint32> (nextInt()))
105  / (static_cast<float> (std::numeric_limits<uint32>::max()) + 1.0f);
106  return jmin (result, 1.0f - std::numeric_limits<float>::epsilon());
107 }
108 
109 double Random::nextDouble() noexcept
110 {
111  return static_cast<uint32> (nextInt()) / (std::numeric_limits<uint32>::max() + 1.0);
112 }
113 
115 {
116  BigInteger n;
117 
118  do
119  {
120  fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1);
121  }
122  while (n >= maximumValue);
123 
124  return n;
125 }
126 
127 void Random::fillBitsRandomly (void* const buffer, size_t bytes)
128 {
129  int* d = static_cast<int*> (buffer);
130 
131  for (; bytes >= sizeof (int); bytes -= sizeof (int))
132  *d++ = nextInt();
133 
134  if (bytes > 0)
135  {
136  const int lastBytes = nextInt();
137  memcpy (d, &lastBytes, bytes);
138  }
139 }
140 
141 void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits)
142 {
143  arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space
144 
145  while ((startBit & 31) != 0 && numBits > 0)
146  {
147  arrayToChange.setBit (startBit++, nextBool());
148  --numBits;
149  }
150 
151  while (numBits >= 32)
152  {
153  arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt());
154  startBit += 32;
155  numBits -= 32;
156  }
157 
158  while (--numBits >= 0)
159  arrayToChange.setBit (startBit + numBits, nextBool());
160 }
161 
162 
163 //==============================================================================
164 //==============================================================================
165 #if JUCE_UNIT_TESTS
166 
167 class RandomTests final : public UnitTest
168 {
169 public:
170  RandomTests()
171  : UnitTest ("Random", UnitTestCategories::maths)
172  {}
173 
174  void runTest() override
175  {
176  beginTest ("Random");
177 
178  Random r = getRandom();
179 
180  for (int i = 2000; --i >= 0;)
181  {
182  expect (r.nextDouble() >= 0.0 && r.nextDouble() < 1.0);
183  expect (r.nextFloat() >= 0.0f && r.nextFloat() < 1.0f);
184  expect (r.nextInt (5) >= 0 && r.nextInt (5) < 5);
185  expect (r.nextInt (1) == 0);
186 
187  int n = r.nextInt (50) + 1;
188  expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
189 
190  n = r.nextInt (0x7ffffffe) + 1;
191  expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
192  }
193  }
194 };
195 
196 static RandomTests randomTests;
197 
198 #endif
199 
200 } // namespace juce
int getHighestBit() const noexcept
BigInteger & setBitRangeAsInt(int startBit, int numBits, uint32 valueToSet)
BigInteger & setBit(int bitNumber)
float nextFloat() noexcept
void fillBitsRandomly(void *bufferToFill, size_t sizeInBytes)
bool nextBool() noexcept
Definition: juce_Random.cpp:97
void setSeedRandomly()
Definition: juce_Random.cpp:55
void combineSeed(int64 seedValue) noexcept
Definition: juce_Random.cpp:50
int nextInt() noexcept
Definition: juce_Random.cpp:74
int64 nextInt64() noexcept
Definition: juce_Random.cpp:92
void setSeed(int64 newSeed) noexcept
Definition: juce_Random.cpp:35
double nextDouble() noexcept
BigInteger nextLargeNumber(const BigInteger &maximumValue)
static Random & getSystemRandom() noexcept
Definition: juce_Random.cpp:67
static int64 getHighResolutionTicks() noexcept
static int64 currentTimeMillis() noexcept
Definition: juce_Time.cpp:220
static int64 getHighResolutionTicksPerSecond() noexcept
static uint32 getMillisecondCounter() noexcept
Definition: juce_Time.cpp:241