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

210 lines
4.4 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
#include "trandom.h"
TRandom::RANDOM_FLOAT_TYPE TRandom::RandomFloatType = TRandom::RANDOM_FLOAT_TYPE_NONE;
TRandom::TRandom(UINT _seed)
: seed(_seed)
{
if (RandomFloatType == TRandom::RANDOM_FLOAT_TYPE_NONE)
setRandomFloatType();
reset();
}
//--------------------------------------------------------------------------
TRandom::~TRandom()
{
}
//--------------------------------------------------------------------------
void TRandom::setSeed(UINT s)
{
seed = s;
reset();
}
//--------------------------------------------------------------------------
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;
}
//--------------------------------------------------------------------------
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);
}
}
//--------------------------------------------------------------------------
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];
}
//--------------------------------------------------------------------------
UINT TRandom::getUInt(UINT end) // [0,end[
{
if (end == 0)
return 0;
UINT u = getNextUINT();
if (end == c_maxuint)
return u;
return u % end;
}
//--------------------------------------------------------------------------
int TRandom::getInt(int begin, int end) // [begin, end[
{
assert(end >= begin);
int limit = end - begin;
if (limit == 0) // end == begin
return begin;
UINT u = getNextUINT();
return u % limit + begin;
}
//--------------------------------------------------------------------------
float TRandom::getFloat() // [0,1[
{
UINT u = getNextUINT();
switch (RandomFloatType) {
case RANDOM_FLOAT_TYPE_1:
u = (u >> 5) & 0x007fffff | 0x3f800000;
break;
case RANDOM_FLOAT_TYPE_2:
u = u & 0xffff7f00 | 0x0000803f;
break;
default:
assert(0);
u = 0;
break;
}
return (*(float *)&u) - 1.0F;
}
//--------------------------------------------------------------------------
float TRandom::getFloat(float end) // [0, end[
{
return getFloat() * end;
}
//--------------------------------------------------------------------------
float TRandom::getFloat(float begin, float end) // [begin, end[
{
assert(end >= begin);
return (getFloat() * (end - begin)) + begin;
}
//--------------------------------------------------------------------------
bool TRandom::getBool()
{
UINT u = getNextUINT();
return u & 1;
}
//--------------------------------------------------------------------------
double TRandom::getDouble() // [0,1[
{
return getFloat();
#ifdef DA_RIVEDERE_O_PROPRIO_IMPLEMENTARE
UINT low = getNextUINT();
UINT high = getNextUINT();
double value = 0;
void *ptr = &value;
UINT *retL = (UINT *)ptr;
UINT *retH = retL + 1;
/*
// questa parte e' stata commentata perche' su tutte le piattaforme il tipo
//di float e' RANDOM_FLOAT_TYPE_1ma su irix c'e' bisogno di eseguire le
//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;
//!!!!!occhio andrebbe sopra il break
return value-1.0;
default: assert (0);
}
return -1;
*/
#ifndef __sgi
*retH = high;
*retH &= 0x007fffff;
*retH |= 0x3ff00000;
*retL = low;
return value - 1.0;
#else
*retH = low;
*retL = (high >> 5) & 0x007fffff | 0x3ff00000;
return value - 1.0;
#endif
#endif
}