| |
| |
| #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) |
| { |
| if (end == 0) return 0; |
| UINT u = getNextUINT(); |
| if (end == c_maxuint) return u; |
| |
| return u % end; |
| } |
| |
| |
| |
| int TRandom::getInt(int begin, int end) |
| { |
| assert(end >= begin); |
| int limit = end - begin; |
| if (limit == 0) |
| return begin; |
| UINT u = getNextUINT(); |
| return u % limit + begin; |
| } |
| |
| |
| |
| float TRandom::getFloat() |
| { |
| 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) |
| { |
| return getFloat() * end; |
| } |
| |
| |
| |
| float TRandom::getFloat(float begin, float end) |
| { |
| assert(end >= begin); |
| return (getFloat() * (end - begin)) + begin; |
| } |
| |
| |
| |
| bool TRandom::getBool() { |
| UINT u = getNextUINT(); |
| return u & 1; |
| } |
| |
| |
| |
| double TRandom::getDouble() |
| { |
| 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; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #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 |
| } |
| |