tahoma2d/toonz/sources/common/tcore/trandom.cpp

196 lines
4.6 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
#include "trandom.h"
2016-06-15 18:43:10 +12:00
TRandom::RANDOM_FLOAT_TYPE TRandom::RandomFloatType =
TRandom::RANDOM_FLOAT_TYPE_NONE;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TRandom::TRandom(UINT _seed) : seed(_seed) {
if (RandomFloatType == TRandom::RANDOM_FLOAT_TYPE_NONE) setRandomFloatType();
reset();
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TRandom::~TRandom() {}
2016-03-19 06:57:51 +13:00
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TRandom::setSeed(UINT s) {
seed = s;
reset();
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TRandom::reset() {
UINT uj, uk;
int i, ii, k;
assert(sizeof(UINT) == 32 / 8);
uj = 161803398 - seed;
ran[55] = uj;
uk = 1;
for (i = 1; i <= 54; i++) {
ii = (21 * i) % 55;
ran[ii] = uk;
uk = uj - uk;
uj = ran[ii];
}
for (k = 1; k <= 4; k++)
for (i = 1; i <= 55; i++) ran[i] -= ran[1 + (i + 30) % 55];
idx1 = 55;
idx2 = 31;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
inline void TRandom::setRandomFloatType() {
UINT u;
assert(sizeof(float) == sizeof(UINT));
u = 0x3f800000;
if ((*(float *)&u) == 1.0F)
RandomFloatType = RANDOM_FLOAT_TYPE_1;
else {
u = 0x0000803f;
if ((*(float *)&u) == 1.0F)
RandomFloatType = RANDOM_FLOAT_TYPE_2;
else
assert(0);
}
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
inline UINT TRandom::getNextUINT() {
idx1++;
if (idx1 == 56) idx1 = 1;
idx2++;
if (idx2 == 56) idx2 = 1;
ran[idx1] = ran[idx1] - ran[idx2];
return ran[idx1];
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
UINT TRandom::getUInt(UINT end) // [0,end[
2016-03-19 06:57:51 +13:00
{
2016-06-15 18:43:10 +12:00
if (end == 0) return 0;
UINT u = getNextUINT();
if (end == c_maxuint) return u;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
return u % end;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
int TRandom::getInt(int begin, int end) // [begin, end[
2016-03-19 06:57:51 +13:00
{
2016-06-15 18:43:10 +12:00
assert(end >= begin);
int limit = end - begin;
if (limit == 0) // end == begin
return begin;
UINT u = getNextUINT();
return u % limit + begin;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
float TRandom::getFloat() // [0,1[
2016-03-19 06:57:51 +13:00
{
2016-06-15 18:43:10 +12:00
UINT u = getNextUINT();
switch (RandomFloatType) {
case RANDOM_FLOAT_TYPE_1:
2020-04-12 17:19:20 +12:00
u = ((u >> 5) & 0x007fffff) | 0x3f800000;
2016-06-15 18:43:10 +12:00
break;
case RANDOM_FLOAT_TYPE_2:
2020-04-12 17:19:20 +12:00
u = (u & 0xffff7f00) | 0x0000803f;
2016-06-15 18:43:10 +12:00
break;
default:
assert(0);
u = 0;
break;
}
return (*(float *)&u) - 1.0F;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
float TRandom::getFloat(float end) // [0, end[
2016-03-19 06:57:51 +13:00
{
2016-06-15 18:43:10 +12:00
return getFloat() * end;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
float TRandom::getFloat(float begin, float end) // [begin, end[
2016-03-19 06:57:51 +13:00
{
2016-06-15 18:43:10 +12:00
assert(end >= begin);
return (getFloat() * (end - begin)) + begin;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
bool TRandom::getBool() {
UINT u = getNextUINT();
return u & 1;
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
double TRandom::getDouble() // [0,1[
2016-03-19 06:57:51 +13:00
{
2016-06-15 18:43:10 +12:00
return getFloat();
2016-03-19 06:57:51 +13:00
#ifdef DA_RIVEDERE_O_PROPRIO_IMPLEMENTARE
2016-06-15 18:43:10 +12:00
UINT low = getNextUINT();
UINT high = getNextUINT();
double value = 0;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
void *ptr = &value;
UINT *retL = (UINT *)ptr;
UINT *retH = retL + 1;
2016-03-19 06:57:51 +13:00
/*
// questa parte e' stata commentata perche' su tutte le piattaforme il tipo
2016-06-15 18:43:10 +12:00
//di float e' RANDOM_FLOAT_TYPE_1ma su irix c'e' bisogno di eseguire le
2016-03-19 06:57:51 +13:00
//istruzioni sotto RANDOM_FLOAT_TYPE_2
switch (RandomFloatType)
{
case RANDOM_FLOAT_TYPE_1:
*retH = high;
*retH &= 0x00efffff;
*retH |= 0x3f000000;
*retL = low ;
// vecchi commenti
// *retH = high;
// *retL = (low >> 5) & 0x007fffff | 0x3ff00000;
return value;
break;
case RANDOM_FLOAT_TYPE_2: *retH = low;
*retL = (high >> 5) & 0x007fffff | 0x3ff00000;
break;
2016-06-15 18:43:10 +12:00
//!!!!!occhio andrebbe sopra il break
2016-03-19 06:57:51 +13:00
return value-1.0;
2016-06-15 18:43:10 +12:00
default: assert (0);
2016-03-19 06:57:51 +13:00
}
return -1;
*/
#ifndef __sgi
2016-06-15 18:43:10 +12:00
*retH = high;
*retH &= 0x007fffff;
*retH |= 0x3ff00000;
*retL = low;
return value - 1.0;
2016-03-19 06:57:51 +13:00
#else
2016-06-15 18:43:10 +12:00
*retH = low;
*retL = (high >> 5) & 0x007fffff | 0x3ff00000;
return value - 1.0;
2016-03-19 06:57:51 +13:00
#endif
#endif
}