131 lines
3.5 KiB
Plaintext
131 lines
3.5 KiB
Plaintext
/* ACC -- Automatic Compiler Configuration
|
|
|
|
Copyright (C) 1996-2003 Markus Franz Xaver Johannes Oberhumer
|
|
All Rights Reserved.
|
|
|
|
This software is a copyrighted work licensed under the terms of
|
|
the GNU General Public License. Please consult the file "ACC_LICENSE"
|
|
for details.
|
|
|
|
Markus F.X.J. Oberhumer
|
|
<markus@oberhumer.com>
|
|
http://www.oberhumer.com/
|
|
*/
|
|
|
|
|
|
#if !defined(ACCLIB_PUBLIC)
|
|
# define ACCLIB_PUBLIC(r,f) r __ACCLIB_FUNCNAME(f)
|
|
#endif
|
|
|
|
|
|
/*************************************************************************
|
|
// some linear congruential pseudo random number generators (PRNG)
|
|
**************************************************************************/
|
|
|
|
ACCLIB_PUBLIC(void, acc_srand31) (acc_rand31_p r, acc_uint32l_t seed)
|
|
{
|
|
r->seed = seed & ACC_UINT32L_C(0xffffffff);
|
|
}
|
|
|
|
ACCLIB_PUBLIC(acc_uint32l_t, acc_rand31) (acc_rand31_p r)
|
|
{
|
|
r->seed = r->seed * ACC_UINT32L_C(1103515245) + 12345;
|
|
r->seed &= ACC_UINT32L_C(0x7fffffff);
|
|
return r->seed;
|
|
}
|
|
|
|
|
|
#if defined(acc_uint64l_t)
|
|
|
|
ACCLIB_PUBLIC(void, acc_srand48) (acc_rand48_p r, acc_uint32l_t seed)
|
|
{
|
|
r->seed = seed & ACC_UINT32L_C(0xffffffff);
|
|
r->seed <<= 16; r->seed |= 0x330e;
|
|
}
|
|
|
|
ACCLIB_PUBLIC(acc_uint32l_t, acc_rand48) (acc_rand48_p r)
|
|
{
|
|
r->seed = r->seed * ACC_UINT64L_C(25214903917) + 11;
|
|
r->seed &= ACC_UINT64L_C(0xffffffffffff);
|
|
return (acc_uint32l_t) (r->seed >> 17);
|
|
}
|
|
|
|
ACCLIB_PUBLIC(acc_uint32l_t, acc_rand48_r32) (acc_rand48_p r)
|
|
{
|
|
r->seed = r->seed * ACC_UINT64L_C(25214903917) + 11;
|
|
r->seed &= ACC_UINT64L_C(0xffffffffffff);
|
|
return (acc_uint32l_t) (r->seed >> 16);
|
|
}
|
|
|
|
#endif /* defined(acc_uint64l_t) */
|
|
|
|
|
|
#if defined(acc_uint64l_t)
|
|
|
|
ACCLIB_PUBLIC(void, acc_srand64) (acc_rand64_p r, acc_uint64l_t seed)
|
|
{
|
|
r->seed = seed & ACC_UINT64L_C(0xffffffffffffffff);
|
|
}
|
|
|
|
ACCLIB_PUBLIC(acc_uint32l_t, acc_rand64) (acc_rand64_p r)
|
|
{
|
|
r->seed = r->seed * ACC_UINT64L_C(6364136223846793005) + 1;
|
|
r->seed &= ACC_UINT64L_C(0xffffffffffffffff);
|
|
return (acc_uint32l_t) (r->seed >> 33);
|
|
}
|
|
|
|
ACCLIB_PUBLIC(acc_uint32l_t, acc_rand64_r32) (acc_rand64_p r)
|
|
{
|
|
r->seed = r->seed * ACC_UINT64L_C(6364136223846793005) + 1;
|
|
r->seed &= ACC_UINT64L_C(0xffffffffffffffff);
|
|
return (acc_uint32l_t) (r->seed >> 32);
|
|
}
|
|
|
|
#endif /* defined(acc_uint64l_t) */
|
|
|
|
|
|
/*************************************************************************
|
|
// mersenne twister PRNG
|
|
**************************************************************************/
|
|
|
|
ACCLIB_PUBLIC(void, acc_srandmt) (acc_randmt_p r, acc_uint32l_t seed)
|
|
{
|
|
unsigned i = 0;
|
|
do {
|
|
r->s[i++] = (seed &= ACC_UINT32L_C(0xffffffff));
|
|
seed ^= seed >> 30;
|
|
seed = seed * ACC_UINT32L_C(0x6c078965) + i;
|
|
} while (i != 624);
|
|
r->n = i;
|
|
}
|
|
|
|
ACCLIB_PUBLIC(acc_uint32l_t, acc_randmt) (acc_randmt_p r)
|
|
{
|
|
return (__ACCLIB_FUNCNAME(acc_randmt_r32)(r)) >> 1;
|
|
}
|
|
|
|
ACCLIB_PUBLIC(acc_uint32l_t, acc_randmt_r32) (acc_randmt_p r)
|
|
{
|
|
acc_uint32l_t v;
|
|
if (r->n == 624) {
|
|
int i = 0, j;
|
|
r->n = i;
|
|
do {
|
|
j = i - 623; if (j < 0) j += 624;
|
|
v = (r->s[i] & ACC_UINT32L_C(0x80000000)) ^ (r->s[j] & ACC_UINT32L_C(0x7fffffff));
|
|
j = i - 227; if (j < 0) j += 624;
|
|
r->s[i] = r->s[j] ^ (v >> 1);
|
|
if (v & 1) r->s[i] ^= ACC_UINT32L_C(0x9908b0df);
|
|
} while (++i != 624);
|
|
}
|
|
v = r->s[r->n++];
|
|
v ^= v >> 11; v ^= (v & ACC_UINT32L_C(0x013a58ad)) << 7;
|
|
v ^= (v & ACC_UINT32L_C(0x0001df8c)) << 15; v ^= v >> 18;
|
|
return v;
|
|
}
|
|
|
|
|
|
/*
|
|
vi:ts=4:et
|
|
*/
|