Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trandom.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRandom::RANDOM_FLOAT_TYPE TRandom::RandomFloatType =
Shinya Kitaoka 120a6e
    TRandom::RANDOM_FLOAT_TYPE_NONE;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRandom::TRandom(UINT _seed) : seed(_seed) {
Shinya Kitaoka 120a6e
  if (RandomFloatType == TRandom::RANDOM_FLOAT_TYPE_NONE) setRandomFloatType();
Shinya Kitaoka 120a6e
  reset();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRandom::~TRandom() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRandom::setSeed(UINT s) {
Shinya Kitaoka 120a6e
  seed = s;
Shinya Kitaoka 120a6e
  reset();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRandom::reset() {
Shinya Kitaoka 120a6e
  UINT uj, uk;
Shinya Kitaoka 120a6e
  int i, ii, k;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(sizeof(UINT) == 32 / 8);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  uj      = 161803398 - seed;
Shinya Kitaoka 120a6e
  ran[55] = uj;
Shinya Kitaoka 120a6e
  uk      = 1;
Shinya Kitaoka 120a6e
  for (i = 1; i <= 54; i++) {
Shinya Kitaoka 120a6e
    ii      = (21 * i) % 55;
Shinya Kitaoka 120a6e
    ran[ii] = uk;
Shinya Kitaoka 120a6e
    uk      = uj - uk;
Shinya Kitaoka 120a6e
    uj      = ran[ii];
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  for (k = 1; k <= 4; k++)
Shinya Kitaoka 120a6e
    for (i = 1; i <= 55; i++) ran[i] -= ran[1 + (i + 30) % 55];
Shinya Kitaoka 120a6e
  idx1     = 55;
Shinya Kitaoka 120a6e
  idx2     = 31;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void TRandom::setRandomFloatType() {
Shinya Kitaoka 120a6e
  UINT u;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(sizeof(float) == sizeof(UINT));
Shinya Kitaoka 120a6e
  u = 0x3f800000;
Shinya Kitaoka 120a6e
  if ((*(float *)&u) == 1.0F)
Shinya Kitaoka 120a6e
    RandomFloatType = RANDOM_FLOAT_TYPE_1;
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    u = 0x0000803f;
Shinya Kitaoka 120a6e
    if ((*(float *)&u) == 1.0F)
Shinya Kitaoka 120a6e
      RandomFloatType = RANDOM_FLOAT_TYPE_2;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      assert(0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline UINT TRandom::getNextUINT() {
Shinya Kitaoka 120a6e
  idx1++;
Shinya Kitaoka 120a6e
  if (idx1 == 56) idx1 = 1;
Shinya Kitaoka 120a6e
  idx2++;
Shinya Kitaoka 120a6e
  if (idx2 == 56) idx2 = 1;
Shinya Kitaoka 120a6e
  ran[idx1]            = ran[idx1] - ran[idx2];
Shinya Kitaoka 120a6e
  return ran[idx1];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TRandom::getUInt(UINT end)  // [0,end[
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  if (end == 0) return 0;
Shinya Kitaoka 120a6e
  UINT u = getNextUINT();
Shinya Kitaoka 120a6e
  if (end == c_maxuint) return u;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return u % end;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TRandom::getInt(int begin, int end)  // [begin, end[
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  assert(end >= begin);
Shinya Kitaoka 120a6e
  int limit = end - begin;
Shinya Kitaoka 120a6e
  if (limit == 0)  // end == begin
Shinya Kitaoka 120a6e
    return begin;
Shinya Kitaoka 120a6e
  UINT u = getNextUINT();
Shinya Kitaoka 120a6e
  return u % limit + begin;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
float TRandom::getFloat()  // [0,1[
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT u = getNextUINT();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (RandomFloatType) {
Shinya Kitaoka 120a6e
  case RANDOM_FLOAT_TYPE_1:
Rozhuk Ivan 823a31
    u = ((u >> 5) & 0x007fffff) | 0x3f800000;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case RANDOM_FLOAT_TYPE_2:
Rozhuk Ivan 823a31
    u = (u & 0xffff7f00) | 0x0000803f;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    assert(0);
Shinya Kitaoka 120a6e
    u = 0;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return (*(float *)&u) - 1.0F;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
float TRandom::getFloat(float end)  // [0, end[
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  return getFloat() * end;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
float TRandom::getFloat(float begin, float end)  // [begin, end[
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  assert(end >= begin);
Shinya Kitaoka 120a6e
  return (getFloat() * (end - begin)) + begin;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRandom::getBool() {
Shinya Kitaoka 120a6e
  UINT u = getNextUINT();
Shinya Kitaoka 120a6e
  return u & 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TRandom::getDouble()  // [0,1[
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  return getFloat();
Toshihiro Shimizu 890ddd
#ifdef DA_RIVEDERE_O_PROPRIO_IMPLEMENTARE
Shinya Kitaoka 120a6e
  UINT low     = getNextUINT();
Shinya Kitaoka 120a6e
  UINT high    = getNextUINT();
Shinya Kitaoka 120a6e
  double value = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void *ptr  = &value;
Shinya Kitaoka 120a6e
  UINT *retL = (UINT *)ptr;
Shinya Kitaoka 120a6e
  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
Shinya Kitaoka 120a6e
//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;
Shinya Kitaoka 120a6e
                                                                                //!!!!!occhio andrebbe sopra il break
Toshihiro Shimizu 890ddd
                             return value-1.0;
Shinya Kitaoka 120a6e
  default: assert (0);
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
return -1;
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
#ifndef __sgi
Shinya Kitaoka 120a6e
  *retH = high;
Shinya Kitaoka 120a6e
  *retH &= 0x007fffff;
Shinya Kitaoka 120a6e
  *retH |= 0x3ff00000;
Shinya Kitaoka 120a6e
  *retL = low;
Shinya Kitaoka 120a6e
  return value - 1.0;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  *retH = low;
Shinya Kitaoka 120a6e
  *retL = (high >> 5) & 0x007fffff | 0x3ff00000;
Shinya Kitaoka 120a6e
  return value - 1.0;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}