OpenShot Audio Library | OpenShotAudio  0.3.1
juce_Random.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
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 Random::~Random() noexcept
36 {
37 }
38 
39 void Random::setSeed (const int64 newSeed) noexcept
40 {
41  if (this == &getSystemRandom())
42  {
43  // Resetting the system Random risks messing up
44  // JUCE's internal state. If you need a predictable
45  // stream of random numbers you should use a local
46  // Random object.
47  jassertfalse;
48  return;
49  }
50 
51  seed = newSeed;
52 }
53 
54 void Random::combineSeed (const int64 seedValue) noexcept
55 {
56  seed ^= nextInt64() ^ seedValue;
57 }
58 
60 {
61  static std::atomic<int64> globalSeed { 0 };
62 
63  combineSeed (globalSeed ^ (int64) (pointer_sized_int) this);
68  globalSeed ^= seed;
69 }
70 
72 {
73  static Random sysRand;
74  return sysRand;
75 }
76 
77 //==============================================================================
78 int Random::nextInt() noexcept
79 {
80  seed = (int64) (((((uint64) seed) * 0x5deece66dLL) + 11) & 0xffffffffffffLL);
81 
82  return (int) (seed >> 16);
83 }
84 
85 int Random::nextInt (const int maxValue) noexcept
86 {
87  jassert (maxValue > 0);
88  return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32);
89 }
90 
91 int Random::nextInt (Range<int> range) noexcept
92 {
93  return range.getStart() + nextInt (range.getLength());
94 }
95 
96 int64 Random::nextInt64() noexcept
97 {
98  return (int64) ((((uint64) (unsigned int) nextInt()) << 32) | (uint64) (unsigned int) nextInt());
99 }
100 
101 bool Random::nextBool() noexcept
102 {
103  return (nextInt() & 0x40000000) != 0;
104 }
105 
106 float Random::nextFloat() noexcept
107 {
108  return static_cast<uint32> (nextInt()) / (std::numeric_limits<uint32>::max() + 1.0f);
109 }
110 
111 double Random::nextDouble() noexcept
112 {
113  return static_cast<uint32> (nextInt()) / (std::numeric_limits<uint32>::max() + 1.0);
114 }
115 
117 {
118  BigInteger n;
119 
120  do
121  {
122  fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1);
123  }
124  while (n >= maximumValue);
125 
126  return n;
127 }
128 
129 void Random::fillBitsRandomly (void* const buffer, size_t bytes)
130 {
131  int* d = static_cast<int*> (buffer);
132 
133  for (; bytes >= sizeof (int); bytes -= sizeof (int))
134  *d++ = nextInt();
135 
136  if (bytes > 0)
137  {
138  const int lastBytes = nextInt();
139  memcpy (d, &lastBytes, bytes);
140  }
141 }
142 
143 void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits)
144 {
145  arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space
146 
147  while ((startBit & 31) != 0 && numBits > 0)
148  {
149  arrayToChange.setBit (startBit++, nextBool());
150  --numBits;
151  }
152 
153  while (numBits >= 32)
154  {
155  arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt());
156  startBit += 32;
157  numBits -= 32;
158  }
159 
160  while (--numBits >= 0)
161  arrayToChange.setBit (startBit + numBits, nextBool());
162 }
163 
164 
165 //==============================================================================
166 //==============================================================================
167 #if JUCE_UNIT_TESTS
168 
169 class RandomTests : public UnitTest
170 {
171 public:
172  RandomTests()
173  : UnitTest ("Random", UnitTestCategories::maths)
174  {}
175 
176  void runTest() override
177  {
178  beginTest ("Random");
179 
180  Random r = getRandom();
181 
182  for (int i = 2000; --i >= 0;)
183  {
184  expect (r.nextDouble() >= 0.0 && r.nextDouble() < 1.0);
185  expect (r.nextFloat() >= 0.0f && r.nextFloat() < 1.0f);
186  expect (r.nextInt (5) >= 0 && r.nextInt (5) < 5);
187  expect (r.nextInt (1) == 0);
188 
189  int n = r.nextInt (50) + 1;
190  expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
191 
192  n = r.nextInt (0x7ffffffe) + 1;
193  expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
194  }
195  }
196 };
197 
198 static RandomTests randomTests;
199 
200 #endif
201 
202 } // namespace juce
int getHighestBit() const noexcept
void setBit(int bitNumber)
void setBitRangeAsInt(int startBit, int numBits, uint32 valueToSet)
float nextFloat() noexcept
void fillBitsRandomly(void *bufferToFill, size_t sizeInBytes)
bool nextBool() noexcept
void setSeedRandomly()
Definition: juce_Random.cpp:59
void combineSeed(int64 seedValue) noexcept
Definition: juce_Random.cpp:54
int nextInt() noexcept
Definition: juce_Random.cpp:78
~Random() noexcept
Definition: juce_Random.cpp:35
int64 nextInt64() noexcept
Definition: juce_Random.cpp:96
void setSeed(int64 newSeed) noexcept
Definition: juce_Random.cpp:39
double nextDouble() noexcept
BigInteger nextLargeNumber(const BigInteger &maximumValue)
static Random & getSystemRandom() noexcept
Definition: juce_Random.cpp:71
static int64 getHighResolutionTicks() noexcept
static int64 currentTimeMillis() noexcept
Definition: juce_Time.cpp:205
static int64 getHighResolutionTicksPerSecond() noexcept
static uint32 getMillisecondCounter() noexcept
Definition: juce_Time.cpp:226