Browse Source

Minor tweaks to Random.

tags/2021-05-28
Julian Storer 14 years ago
parent
commit
a1abff979b
12 changed files with 65 additions and 62 deletions
  1. +3
    -2
      src/audio/dsp/juce_AudioDataConverters.cpp
  2. +4
    -2
      src/containers/juce_AbstractFifo.cpp
  3. +19
    -25
      src/core/juce_Uuid.cpp
  4. +3
    -3
      src/cryptography/juce_Primes.cpp
  5. +2
    -1
      src/gui/components/mouse/juce_DragAndDropContainer.cpp
  6. +5
    -3
      src/gui/components/windows/juce_ComponentPeer.cpp
  7. +1
    -1
      src/io/files/juce_File.cpp
  8. +3
    -2
      src/io/files/juce_TemporaryFile.cpp
  9. +7
    -6
      src/io/streams/juce_MemoryInputStream.cpp
  10. +5
    -2
      src/maths/juce_Random.cpp
  11. +9
    -12
      src/maths/juce_Random.h
  12. +4
    -3
      src/text/juce_String.cpp

+ 3
- 2
src/audio/dsp/juce_AudioDataConverters.cpp View File

@@ -504,6 +504,7 @@ public:
{ {
const int numSamples = 2048; const int numSamples = 2048;
int32 original [numSamples], converted [numSamples], reversed [numSamples]; int32 original [numSamples], converted [numSamples], reversed [numSamples];
Random r;
{ {
AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst> d (original); AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst> d (original);
@@ -511,13 +512,13 @@ public:
for (int i = 0; i < numSamples / 2; ++i) for (int i = 0; i < numSamples / 2; ++i)
{ {
d.setAsFloat (Random::getSystemRandom().nextFloat() * 2.2f - 1.1f);
d.setAsFloat (r.nextFloat() * 2.2f - 1.1f);
if (! d.isFloatingPoint()) if (! d.isFloatingPoint())
clippingFailed = d.getAsFloat() > 1.0f || d.getAsFloat() < -1.0f || clippingFailed; clippingFailed = d.getAsFloat() > 1.0f || d.getAsFloat() < -1.0f || clippingFailed;
++d; ++d;
d.setAsInt32 (Random::getSystemRandom().nextInt());
d.setAsInt32 (r.nextInt());
++d; ++d;
} }


+ 4
- 2
src/containers/juce_AbstractFifo.cpp View File

@@ -165,10 +165,11 @@ public:
void run() void run()
{ {
int n = 0; int n = 0;
Random r;
while (! threadShouldExit()) while (! threadShouldExit())
{ {
int num = Random::getSystemRandom().nextInt (2000) + 1;
int num = r.nextInt (2000) + 1;
int start1, size1, start2, size2; int start1, size1, start2, size2;
fifo.prepareToWrite (num, start1, size1, start2, size2); fifo.prepareToWrite (num, start1, size1, start2, size2);
@@ -203,10 +204,11 @@ public:
WriteThread writer (fifo, buffer); WriteThread writer (fifo, buffer);
int n = 0; int n = 0;
Random r;
for (int count = 1000000; --count >= 0;) for (int count = 1000000; --count >= 0;)
{ {
int num = Random::getSystemRandom().nextInt (6000) + 1;
int num = r.nextInt (6000) + 1;
int start1, size1, start2, size2; int start1, size1, start2, size2;
fifo.prepareToRead (num, start1, size1, start2, size2); fifo.prepareToRead (num, start1, size1, start2, size2);


+ 19
- 25
src/core/juce_Uuid.cpp View File

@@ -33,42 +33,36 @@ BEGIN_JUCE_NAMESPACE
#include "../io/network/juce_MACAddress.h" #include "../io/network/juce_MACAddress.h"
#include "../memory/juce_MemoryBlock.h" #include "../memory/juce_MemoryBlock.h"
//==============================================================================
Uuid::Uuid()
namespace
{ {
// Mix up any available MAC addresses with some time-based pseudo-random numbers
// to make it very very unlikely that two UUIDs will ever be the same..
static int64 macAddresses[2];
static bool hasCheckedMacAddresses = false;
if (! hasCheckedMacAddresses)
int64 getRandomSeedFromMACAddresses()
{ {
hasCheckedMacAddresses = true;
Array<MACAddress> result; Array<MACAddress> result;
MACAddress::findAllAddresses (result); MACAddress::findAllAddresses (result);
for (int i = 0; i < numElementsInArray (macAddresses); ++i)
macAddresses[i] = result[i].toInt64();
Random r;
for (int i = 0; i < result.size(); ++i)
r.combineSeed (result[i].toInt64());
return r.nextInt64();
} }
}
value.asInt64[0] = macAddresses[0];
value.asInt64[1] = macAddresses[1];
//==============================================================================
Uuid::Uuid()
{
// The normal random seeding is pretty good, but we'll throw some MAC addresses
// into the mix too, to make it very very unlikely that two UUIDs will ever be the same..
// We'll use both a local RNG that is re-seeded, plus the shared RNG,
// whose seed will carry over between calls to this method.
static Random r1 (getRandomSeedFromMACAddresses());
Random r (macAddresses[0] ^ macAddresses[1]
^ Random::getSystemRandom().nextInt64());
value.asInt64[0] = r1.nextInt64();
value.asInt64[1] = r1.nextInt64();
Random r2;
for (int i = 4; --i >= 0;) for (int i = 4; --i >= 0;)
{
r.setSeedRandomly(); // calling this repeatedly improves randomness
value.asInt[i] ^= r.nextInt();
value.asInt[i] ^= Random::getSystemRandom().nextInt();
}
value.asInt[i] ^= r2.nextInt();
} }
Uuid::~Uuid() noexcept Uuid::~Uuid() noexcept


+ 3
- 3
src/cryptography/juce_Primes.cpp View File

@@ -171,14 +171,14 @@ BigInteger Primes::createProbablePrime (const int bitLength,
{ {
randomSeeds = defaultSeeds; randomSeeds = defaultSeeds;
numRandomSeeds = numElementsInArray (defaultSeeds); numRandomSeeds = numElementsInArray (defaultSeeds);
Random r;
Random r1, r2;
for (int j = 10; --j >= 0;) for (int j = 10; --j >= 0;)
{ {
r.setSeedRandomly();
r1.setSeedRandomly();
for (int i = numRandomSeeds; --i >= 0;) for (int i = numRandomSeeds; --i >= 0;)
defaultSeeds[i] ^= r.nextInt() ^ Random::getSystemRandom().nextInt();
defaultSeeds[i] ^= r1.nextInt() ^ r2.nextInt();
} }
} }


+ 2
- 1
src/gui/components/mouse/juce_DragAndDropContainer.cpp View File

@@ -359,6 +359,7 @@ void DragAndDropContainer::startDragging (const var& sourceDescription,
Point<int> relPos (sourceComponent->getLocalPoint (nullptr, lastMouseDown)); Point<int> relPos (sourceComponent->getLocalPoint (nullptr, lastMouseDown));
Point<int> clipped (dragImage.getBounds().getConstrainedPoint (relPos)); Point<int> clipped (dragImage.getBounds().getConstrainedPoint (relPos));
Random random;
for (int y = dragImage.getHeight(); --y >= 0;) for (int y = dragImage.getHeight(); --y >= 0;)
{ {
@@ -373,7 +374,7 @@ void DragAndDropContainer::startDragging (const var& sourceDescription,
{ {
const float alpha = (distance > hi) ? 0 const float alpha = (distance > hi) ? 0
: (hi - distance) / (float) (hi - lo) : (hi - distance) / (float) (hi - lo)
+ Random::getSystemRandom().nextFloat() * 0.008f;
+ random.nextFloat() * 0.008f;
dragImage.multiplyAlphaAt (x, y, alpha); dragImage.multiplyAlphaAt (x, y, alpha);
} }


+ 5
- 3
src/gui/components/windows/juce_ComponentPeer.cpp View File

@@ -135,9 +135,11 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo)
// clearly when things are being repainted. // clearly when things are being repainted.
g.restoreState(); g.restoreState();
g.fillAll (Colour ((uint8) Random::getSystemRandom().nextInt (255),
(uint8) Random::getSystemRandom().nextInt (255),
(uint8) Random::getSystemRandom().nextInt (255),
static Random rng;
g.fillAll (Colour ((uint8) rng.nextInt (255),
(uint8) rng.nextInt (255),
(uint8) rng.nextInt (255),
(uint8) 0x50)); (uint8) 0x50));
#endif #endif


+ 1
- 1
src/io/files/juce_File.cpp View File

@@ -890,7 +890,7 @@ String File::getRelativePathFrom (const File& dir) const
File File::createTempFile (const String& fileNameEnding) File File::createTempFile (const String& fileNameEnding)
{ {
const File tempFile (getSpecialLocation (tempDirectory) const File tempFile (getSpecialLocation (tempDirectory)
.getChildFile ("temp_" + String (Random::getSystemRandom().nextInt()))
.getChildFile ("temp_" + String::toHexString (Random::getSystemRandom().nextInt()))
.withFileExtension (fileNameEnding)); .withFileExtension (fileNameEnding));
if (tempFile.exists()) if (tempFile.exists())


+ 3
- 2
src/io/files/juce_TemporaryFile.cpp View File

@@ -36,7 +36,7 @@ BEGIN_JUCE_NAMESPACE
TemporaryFile::TemporaryFile (const String& suffix, const int optionFlags) TemporaryFile::TemporaryFile (const String& suffix, const int optionFlags)
{ {
createTempFile (File::getSpecialLocation (File::tempDirectory), createTempFile (File::getSpecialLocation (File::tempDirectory),
"temp_" + String (Random::getSystemRandom().nextInt()),
"temp_" + String::toHexString (Random::getSystemRandom().nextInt()),
suffix, suffix,
optionFlags); optionFlags);
} }
@@ -48,7 +48,8 @@ TemporaryFile::TemporaryFile (const File& targetFile_, const int optionFlags)
jassert (targetFile != File::nonexistent); jassert (targetFile != File::nonexistent);
createTempFile (targetFile.getParentDirectory(), createTempFile (targetFile.getParentDirectory(),
targetFile.getFileNameWithoutExtension() + "_temp" + String (Random::getSystemRandom().nextInt()),
targetFile.getFileNameWithoutExtension()
+ "_temp" + String::toHexString (Random::getSystemRandom().nextInt()),
targetFile.getFileExtension(), targetFile.getFileExtension(),
optionFlags); optionFlags);
} }


+ 7
- 6
src/io/streams/juce_MemoryInputStream.cpp View File

@@ -113,10 +113,11 @@ public:
void runTest() void runTest()
{ {
beginTest ("Basics"); beginTest ("Basics");
Random r;
int randomInt = Random::getSystemRandom().nextInt();
int64 randomInt64 = Random::getSystemRandom().nextInt64();
double randomDouble = Random::getSystemRandom().nextDouble();
int randomInt = r.nextInt();
int64 randomInt64 = r.nextInt64();
double randomDouble = r.nextDouble();
String randomString (createRandomWideCharString()); String randomString (createRandomWideCharString());
MemoryOutputStream mo; MemoryOutputStream mo;
@@ -146,16 +147,16 @@ public:
for (int i = 0; i < numElementsInArray (buffer) - 1; ++i) for (int i = 0; i < numElementsInArray (buffer) - 1; ++i)
{ {
if (Random::getSystemRandom().nextBool())
if (r.nextBool())
{ {
do do
{ {
buffer[i] = (juce_wchar) (1 + Random::getSystemRandom().nextInt (0x10ffff - 1));
buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1));
} }
while (! CharPointer_UTF16::canRepresent (buffer[i])); while (! CharPointer_UTF16::canRepresent (buffer[i]));
} }
else else
buffer[i] = (juce_wchar) (1 + Random::getSystemRandom().nextInt (0xff));
buffer[i] = (juce_wchar) (1 + r.nextInt (0xff));
} }
return CharPointer_UTF32 (buffer); return CharPointer_UTF32 (buffer);


+ 5
- 2
src/maths/juce_Random.cpp View File

@@ -59,11 +59,14 @@ void Random::combineSeed (const int64 seedValue) noexcept
void Random::setSeedRandomly() void Random::setSeedRandomly()
{ {
combineSeed ((int64) (pointer_sized_int) this);
static int64 globalSeed = 0;
combineSeed (globalSeed ^ (int64) (pointer_sized_int) this);
combineSeed (Time::getMillisecondCounter()); combineSeed (Time::getMillisecondCounter());
combineSeed (Time::getHighResolutionTicks()); combineSeed (Time::getHighResolutionTicks());
combineSeed (Time::getHighResolutionTicksPerSecond()); combineSeed (Time::getHighResolutionTicksPerSecond());
combineSeed (Time::currentTimeMillis()); combineSeed (Time::currentTimeMillis());
globalSeed ^= seed;
} }
Random& Random::getSystemRandom() noexcept Random& Random::getSystemRandom() noexcept
@@ -83,7 +86,7 @@ int Random::nextInt() noexcept
int Random::nextInt (const int maxValue) noexcept int Random::nextInt (const int maxValue) noexcept
{ {
jassert (maxValue > 0); jassert (maxValue > 0);
return (nextInt() & 0x7fffffff) % maxValue;
return (((unsigned int) nextInt()) * (uint64) maxValue) >> 32;
} }
int64 Random::nextInt64() noexcept int64 Random::nextInt64() noexcept


+ 9
- 12
src/maths/juce_Random.h View File

@@ -34,9 +34,6 @@
A random number generator. A random number generator.
You can create a Random object and use it to generate a sequence of random numbers. You can create a Random object and use it to generate a sequence of random numbers.
As a handy shortcut to avoid having to create and seed one yourself, you can call
Random::getSystemRandom() to return a global RNG that is seeded randomly when the
app launches.
*/ */
class JUCE_API Random class JUCE_API Random
{ {
@@ -67,7 +64,7 @@ public:
int nextInt() noexcept; int nextInt() noexcept;
/** Returns the next random number, limited to a given range. /** Returns the next random number, limited to a given range.
The maxValue parameter may not be negative, or zero.
@returns a random integer between 0 (inclusive) and maxValue (exclusive). @returns a random integer between 0 (inclusive) and maxValue (exclusive).
*/ */
int nextInt (int maxValue) noexcept; int nextInt (int maxValue) noexcept;
@@ -104,14 +101,6 @@ public:
void fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits); void fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits);
//============================================================================== //==============================================================================
/** To avoid the overhead of having to create a new Random object whenever
you need a number, this is a shared application-wide object that
can be used.
It's not thread-safe though, so threads should use their own Random object.
*/
static Random& getSystemRandom() noexcept;
/** Resets this Random object to a given seed value. */ /** Resets this Random object to a given seed value. */
void setSeed (int64 newSeed) noexcept; void setSeed (int64 newSeed) noexcept;
@@ -129,6 +118,14 @@ public:
*/ */
void setSeedRandomly(); void setSeedRandomly();
/** The overhead of creating a new Random object is fairly small, but if you want to avoid
it, you can call this method to get a global shared Random object.
It's not thread-safe though, so threads should use their own Random object, otherwise
you run the risk of your random numbers becoming.. erm.. randomly corrupted..
*/
static Random& getSystemRandom() noexcept;
private: private:
//============================================================================== //==============================================================================
int64 seed; int64 seed;


+ 4
- 3
src/text/juce_String.cpp View File

@@ -2161,19 +2161,20 @@ public:
static String createRandomWideCharString() static String createRandomWideCharString()
{ {
juce_wchar buffer[50] = { 0 }; juce_wchar buffer[50] = { 0 };
Random r;
for (int i = 0; i < numElementsInArray (buffer) - 1; ++i) for (int i = 0; i < numElementsInArray (buffer) - 1; ++i)
{ {
if (Random::getSystemRandom().nextBool())
if (r.nextBool())
{ {
do do
{ {
buffer[i] = (juce_wchar) (1 + Random::getSystemRandom().nextInt (0x10ffff - 1));
buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1));
} }
while (! CharPointer_UTF16::canRepresent (buffer[i])); while (! CharPointer_UTF16::canRepresent (buffer[i]));
} }
else else
buffer[i] = (juce_wchar) (1 + Random::getSystemRandom().nextInt (0xff));
buffer[i] = (juce_wchar) (1 + r.nextInt (0xff));
} }
return CharPointer_UTF32 (buffer); return CharPointer_UTF32 (buffer);


Loading…
Cancel
Save