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
}