Loading...
Searching...
No Matches
juce_Random.cpp
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
Random::Random (int64 seedValue) noexcept : seed (seedValue)
{
}
Random::Random() : seed (1)
{
setSeedRandomly();
}
void Random::setSeed (const int64 newSeed) noexcept
{
if (this == &getSystemRandom())
{
// Resetting the system Random risks messing up
// JUCE's internal state. If you need a predictable
// stream of random numbers you should use a local
// Random object.
jassertfalse;
return;
}
seed = newSeed;
}
void Random::combineSeed (const int64 seedValue) noexcept
{
seed ^= nextInt64() ^ seedValue;
}
void Random::setSeedRandomly()
{
static std::atomic<int64> globalSeed { 0 };
combineSeed (globalSeed ^ (int64) (pointer_sized_int) this);
combineSeed (Time::getMillisecondCounter());
combineSeed (Time::getHighResolutionTicks());
combineSeed (Time::getHighResolutionTicksPerSecond());
combineSeed (Time::currentTimeMillis());
globalSeed ^= seed;
}
Random& Random::getSystemRandom() noexcept
{
static Random sysRand;
return sysRand;
}
//==============================================================================
int Random::nextInt() noexcept
{
seed = (int64) (((((uint64) seed) * 0x5deece66dLL) + 11) & 0xffffffffffffLL);
return (int) (seed >> 16);
}
int Random::nextInt (const int maxValue) noexcept
{
jassert (maxValue > 0);
return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32);
}
int Random::nextInt (Range<int> range) noexcept
{
return range.getStart() + nextInt (range.getLength());
}
int64 Random::nextInt64() noexcept
{
return (int64) ((((uint64) (unsigned int) nextInt()) << 32) | (uint64) (unsigned int) nextInt());
}
bool Random::nextBool() noexcept
{
return (nextInt() & 0x40000000) != 0;
}
float Random::nextFloat() noexcept
{
auto result = static_cast<float> (static_cast<uint32> (nextInt()))
/ (static_cast<float> (std::numeric_limits<uint32>::max()) + 1.0f);
return jmin (result, 1.0f - std::numeric_limits<float>::epsilon());
}
double Random::nextDouble() noexcept
{
return static_cast<uint32> (nextInt()) / (std::numeric_limits<uint32>::max() + 1.0);
}
BigInteger Random::nextLargeNumber (const BigInteger& maximumValue)
{
BigInteger n;
do
{
fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1);
}
while (n >= maximumValue);
return n;
}
void Random::fillBitsRandomly (void* const buffer, size_t bytes)
{
int* d = static_cast<int*> (buffer);
for (; bytes >= sizeof (int); bytes -= sizeof (int))
*d++ = nextInt();
if (bytes > 0)
{
const int lastBytes = nextInt();
memcpy (d, &lastBytes, bytes);
}
}
void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits)
{
arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space
while ((startBit & 31) != 0 && numBits > 0)
{
arrayToChange.setBit (startBit++, nextBool());
--numBits;
}
while (numBits >= 32)
{
arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt());
startBit += 32;
numBits -= 32;
}
while (--numBits >= 0)
arrayToChange.setBit (startBit + numBits, nextBool());
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class RandomTests final : public UnitTest
{
public:
RandomTests()
: UnitTest ("Random", UnitTestCategories::maths)
{}
void runTest() override
{
beginTest ("Random");
Random r = getRandom();
for (int i = 2000; --i >= 0;)
{
expect (r.nextDouble() >= 0.0 && r.nextDouble() < 1.0);
expect (r.nextFloat() >= 0.0f && r.nextFloat() < 1.0f);
expect (r.nextInt (5) >= 0 && r.nextInt (5) < 5);
expect (r.nextInt (1) == 0);
int n = r.nextInt (50) + 1;
expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
n = r.nextInt (0x7ffffffe) + 1;
expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
}
}
};
static RandomTests randomTests;
#endif
} // namespace juce
juce::BigInteger
Definition juce_BigInteger.h:39
juce::BigInteger::getHighestBit
int getHighestBit() const noexcept
Definition juce_BigInteger.cpp:391
juce::BigInteger::setBitRangeAsInt
BigInteger & setBitRangeAsInt(int startBit, int numBits, uint32 valueToSet)
Definition juce_BigInteger.cpp:263
juce::BigInteger::setBit
BigInteger & setBit(int bitNumber)
Definition juce_BigInteger.cpp:294
juce::Random::nextFloat
float nextFloat() noexcept
Definition juce_Random.cpp:102
juce::Random::Random
Random()
Definition juce_Random.cpp:30
juce::Random::fillBitsRandomly
void fillBitsRandomly(void *bufferToFill, size_t sizeInBytes)
Definition juce_Random.cpp:127
juce::Random::nextBool
bool nextBool() noexcept
Definition juce_Random.cpp:97
juce::Random::setSeedRandomly
void setSeedRandomly()
Definition juce_Random.cpp:55
juce::Random::combineSeed
void combineSeed(int64 seedValue) noexcept
Definition juce_Random.cpp:50
juce::Random::nextInt
int nextInt() noexcept
Definition juce_Random.cpp:74
juce::Random::nextInt64
int64 nextInt64() noexcept
Definition juce_Random.cpp:92
juce::Random::setSeed
void setSeed(int64 newSeed) noexcept
Definition juce_Random.cpp:35
juce::Random::nextDouble
double nextDouble() noexcept
Definition juce_Random.cpp:109
juce::Random::nextLargeNumber
BigInteger nextLargeNumber(const BigInteger &maximumValue)
Definition juce_Random.cpp:114
juce::Random::Random
Random(int64 seedValue) noexcept
Definition juce_Random.cpp:26
juce::Random::getSystemRandom
static Random & getSystemRandom() noexcept
Definition juce_Random.cpp:67
juce::Range
Definition juce_Range.h:40
juce::Time::getHighResolutionTicks
static int64 getHighResolutionTicks() noexcept
juce::Time::currentTimeMillis
static int64 currentTimeMillis() noexcept
Definition juce_Time.cpp:220
juce::Time::getHighResolutionTicksPerSecond
static int64 getHighResolutionTicksPerSecond() noexcept
juce::Time::getMillisecondCounter
static uint32 getMillisecondCounter() noexcept
Definition juce_Time.cpp:241
juce::UnitTest
Definition juce_UnitTest.h:70