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