added further fixes, and upgrades
This commit is contained in:
107
TSE_Math/src/Random.cpp
Normal file
107
TSE_Math/src/Random.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "Random.hpp"
|
||||
#include <bit>
|
||||
#include <cstdint>
|
||||
|
||||
TSE::Random::Random(uint seed)
|
||||
{
|
||||
state = static_cast<uint>(static_cast<std::uint32_t>(seed));
|
||||
}
|
||||
|
||||
TSE::uint TSE::Random::nextUInt(uint minInc, uint maxInc)
|
||||
{
|
||||
constexpr std::uint32_t multiplier = 1664525u;
|
||||
constexpr std::uint32_t increment = 1013904223u;
|
||||
|
||||
std::uint32_t nextState = static_cast<std::uint32_t>(state);
|
||||
nextState = nextState * multiplier + increment;
|
||||
state = static_cast<uint>(nextState);
|
||||
|
||||
if(minInc == 0u && maxInc == 0u)
|
||||
{
|
||||
return state;
|
||||
}
|
||||
|
||||
if(minInc > maxInc)
|
||||
{
|
||||
uint temp = minInc;
|
||||
minInc = maxInc;
|
||||
maxInc = temp;
|
||||
}
|
||||
|
||||
const std::uint64_t span = static_cast<std::uint64_t>(maxInc) - static_cast<std::uint64_t>(minInc) + 1ull;
|
||||
const std::uint64_t offset = static_cast<std::uint64_t>(nextState) % span;
|
||||
return static_cast<uint>(static_cast<std::uint64_t>(minInc) + offset);
|
||||
}
|
||||
|
||||
int TSE::Random::nextInt(int minInc, int maxInc)
|
||||
{
|
||||
const std::uint32_t bits = static_cast<std::uint32_t>(nextUInt());
|
||||
|
||||
if(minInc == 0 && maxInc == 0)
|
||||
{
|
||||
return static_cast<int>(std::bit_cast<std::int32_t>(bits));
|
||||
}
|
||||
|
||||
if(minInc > maxInc)
|
||||
{
|
||||
int temp = minInc;
|
||||
minInc = maxInc;
|
||||
maxInc = temp;
|
||||
}
|
||||
|
||||
const std::int64_t span = static_cast<std::int64_t>(maxInc) - static_cast<std::int64_t>(minInc) + 1ll;
|
||||
const std::uint64_t offset = static_cast<std::uint64_t>(bits) % static_cast<std::uint64_t>(span);
|
||||
const std::int64_t value = static_cast<std::int64_t>(minInc) + static_cast<std::int64_t>(offset);
|
||||
return static_cast<int>(value);
|
||||
}
|
||||
|
||||
short TSE::Random::nextShort(short minInc, short maxInc)
|
||||
{
|
||||
const std::uint32_t bits = static_cast<std::uint32_t>(nextUInt());
|
||||
const std::uint16_t lowerBits = static_cast<std::uint16_t>(bits);
|
||||
|
||||
if(minInc == 0 && maxInc == 0)
|
||||
{
|
||||
return static_cast<short>(std::bit_cast<std::int16_t>(lowerBits));
|
||||
}
|
||||
|
||||
if(minInc > maxInc)
|
||||
{
|
||||
short temp = minInc;
|
||||
minInc = maxInc;
|
||||
maxInc = temp;
|
||||
}
|
||||
|
||||
const std::int32_t span = static_cast<std::int32_t>(maxInc) - static_cast<std::int32_t>(minInc) + 1;
|
||||
const std::uint32_t offset = static_cast<std::uint32_t>(lowerBits) % static_cast<std::uint32_t>(span);
|
||||
const std::int32_t value = static_cast<std::int32_t>(minInc) + static_cast<std::int32_t>(offset);
|
||||
return static_cast<short>(value);
|
||||
}
|
||||
|
||||
TSE::byte TSE::Random::nextByte(byte minInc, byte maxInc)
|
||||
{
|
||||
const std::uint32_t bits = static_cast<std::uint32_t>(nextUInt());
|
||||
const std::uint8_t lowerBits = static_cast<std::uint8_t>(bits);
|
||||
|
||||
if(minInc == 0 && maxInc == 0)
|
||||
{
|
||||
return static_cast<byte>(lowerBits);
|
||||
}
|
||||
|
||||
if(minInc > maxInc)
|
||||
{
|
||||
byte temp = minInc;
|
||||
minInc = maxInc;
|
||||
maxInc = temp;
|
||||
}
|
||||
|
||||
const std::uint16_t span = static_cast<std::uint16_t>(maxInc) - static_cast<std::uint16_t>(minInc) + 1u;
|
||||
const std::uint16_t offset = static_cast<std::uint16_t>(lowerBits) % span;
|
||||
return static_cast<byte>(static_cast<std::uint16_t>(minInc) + offset);
|
||||
}
|
||||
|
||||
float TSE::Random::nextFloat01()
|
||||
{
|
||||
constexpr float invRange = 1.0f / 4294967296.0f;
|
||||
return static_cast<float>(static_cast<std::uint32_t>(nextUInt())) * invRange;
|
||||
}
|
||||
Reference in New Issue
Block a user