Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 26 | pmbaty | 1 | /* ACC -- Automatic Compiler Configuration  | 
        
| 2 | |||
| 3 | Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer  | 
        ||
| 4 | All Rights Reserved.  | 
        ||
| 5 | |||
| 6 | This software is a copyrighted work licensed under the terms of  | 
        ||
| 7 | the GNU General Public License. Please consult the file "ACC_LICENSE"  | 
        ||
| 8 | for details.  | 
        ||
| 9 | |||
| 10 | Markus F.X.J. Oberhumer  | 
        ||
| 11 | <markus@oberhumer.com>  | 
        ||
| 12 | http://www.oberhumer.com/  | 
        ||
| 13 | */  | 
        ||
| 14 | |||
| 15 | |||
| 16 | #define __ACCLIB_RAND_CH_INCLUDED 1  | 
        ||
| 17 | #if !defined(ACCLIB_PUBLIC)  | 
        ||
| 18 | # define ACCLIB_PUBLIC(r,f) r __ACCLIB_FUNCNAME(f)  | 
        ||
| 19 | #endif  | 
        ||
| 20 | |||
| 21 | |||
| 22 | /*************************************************************************  | 
        ||
| 23 | // some linear congruential pseudo random number generators (PRNG)  | 
        ||
| 24 | **************************************************************************/  | 
        ||
| 25 | |||
| 26 | ACCLIB_PUBLIC(void, acc_srand31) (acc_rand31_p r, acc_uint32l_t seed)  | 
        ||
| 27 | { | 
        ||
| 28 | r->seed = seed & ACC_UINT32L_C(0xffffffff);  | 
        ||
| 29 | }  | 
        ||
| 30 | |||
| 31 | ACCLIB_PUBLIC(acc_uint32l_t, acc_rand31) (acc_rand31_p r)  | 
        ||
| 32 | { | 
        ||
| 33 | r->seed = r->seed * ACC_UINT32L_C(1103515245) + 12345;  | 
        ||
| 34 | r->seed &= ACC_UINT32L_C(0x7fffffff);  | 
        ||
| 35 | return r->seed;  | 
        ||
| 36 | }  | 
        ||
| 37 | |||
| 38 | |||
| 39 | #if defined(acc_uint64l_t)  | 
        ||
| 40 | |||
| 41 | ACCLIB_PUBLIC(void, acc_srand48) (acc_rand48_p r, acc_uint32l_t seed)  | 
        ||
| 42 | { | 
        ||
| 43 | r->seed = seed & ACC_UINT32L_C(0xffffffff);  | 
        ||
| 44 | r->seed <<= 16; r->seed |= 0x330e;  | 
        ||
| 45 | }  | 
        ||
| 46 | |||
| 47 | ACCLIB_PUBLIC(acc_uint32l_t, acc_rand48) (acc_rand48_p r)  | 
        ||
| 48 | { | 
        ||
| 49 | r->seed = r->seed * ACC_UINT64L_C(25214903917) + 11;  | 
        ||
| 50 | r->seed &= ACC_UINT64L_C(0xffffffffffff);  | 
        ||
| 51 | return (acc_uint32l_t) (r->seed >> 17);  | 
        ||
| 52 | }  | 
        ||
| 53 | |||
| 54 | ACCLIB_PUBLIC(acc_uint32l_t, acc_rand48_r32) (acc_rand48_p r)  | 
        ||
| 55 | { | 
        ||
| 56 | r->seed = r->seed * ACC_UINT64L_C(25214903917) + 11;  | 
        ||
| 57 | r->seed &= ACC_UINT64L_C(0xffffffffffff);  | 
        ||
| 58 | return (acc_uint32l_t) (r->seed >> 16);  | 
        ||
| 59 | }  | 
        ||
| 60 | |||
| 61 | #endif /* acc_uint64l_t */  | 
        ||
| 62 | |||
| 63 | |||
| 64 | #if defined(acc_uint64l_t)  | 
        ||
| 65 | |||
| 66 | ACCLIB_PUBLIC(void, acc_srand64) (acc_rand64_p r, acc_uint64l_t seed)  | 
        ||
| 67 | { | 
        ||
| 68 | r->seed = seed & ACC_UINT64L_C(0xffffffffffffffff);  | 
        ||
| 69 | }  | 
        ||
| 70 | |||
| 71 | ACCLIB_PUBLIC(acc_uint32l_t, acc_rand64) (acc_rand64_p r)  | 
        ||
| 72 | { | 
        ||
| 73 | r->seed = r->seed * ACC_UINT64L_C(6364136223846793005) + 1;  | 
        ||
| 74 | #if (SIZEOF_ACC_INT64L_T > 8)  | 
        ||
| 75 | r->seed &= ACC_UINT64L_C(0xffffffffffffffff);  | 
        ||
| 76 | #endif  | 
        ||
| 77 | return (acc_uint32l_t) (r->seed >> 33);  | 
        ||
| 78 | }  | 
        ||
| 79 | |||
| 80 | ACCLIB_PUBLIC(acc_uint32l_t, acc_rand64_r32) (acc_rand64_p r)  | 
        ||
| 81 | { | 
        ||
| 82 | r->seed = r->seed * ACC_UINT64L_C(6364136223846793005) + 1;  | 
        ||
| 83 | #if (SIZEOF_ACC_INT64L_T > 8)  | 
        ||
| 84 | r->seed &= ACC_UINT64L_C(0xffffffffffffffff);  | 
        ||
| 85 | #endif  | 
        ||
| 86 | return (acc_uint32l_t) (r->seed >> 32);  | 
        ||
| 87 | }  | 
        ||
| 88 | |||
| 89 | #endif /* acc_uint64l_t */  | 
        ||
| 90 | |||
| 91 | |||
| 92 | /*************************************************************************  | 
        ||
| 93 | // mersenne twister PRNG  | 
        ||
| 94 | **************************************************************************/  | 
        ||
| 95 | |||
| 96 | ACCLIB_PUBLIC(void, acc_srandmt) (acc_randmt_p r, acc_uint32l_t seed)  | 
        ||
| 97 | { | 
        ||
| 98 | unsigned i = 0;  | 
        ||
| 99 |     do { | 
        ||
| 100 | r->s[i++] = (seed &= ACC_UINT32L_C(0xffffffff));  | 
        ||
| 101 | seed ^= seed >> 30;  | 
        ||
| 102 | seed = seed * ACC_UINT32L_C(0x6c078965) + i;  | 
        ||
| 103 | } while (i != 624);  | 
        ||
| 104 | r->n = i;  | 
        ||
| 105 | }  | 
        ||
| 106 | |||
| 107 | ACCLIB_PUBLIC(acc_uint32l_t, acc_randmt) (acc_randmt_p r)  | 
        ||
| 108 | { | 
        ||
| 109 | return (__ACCLIB_FUNCNAME(acc_randmt_r32)(r)) >> 1;  | 
        ||
| 110 | }  | 
        ||
| 111 | |||
| 112 | ACCLIB_PUBLIC(acc_uint32l_t, acc_randmt_r32) (acc_randmt_p r)  | 
        ||
| 113 | { | 
        ||
| 114 | acc_uint32l_t v;  | 
        ||
| 115 |     if (r->n == 624) { | 
        ||
| 116 | int i = 0, j;  | 
        ||
| 117 | r->n = 0;  | 
        ||
| 118 |         do { | 
        ||
| 119 | j = i - 623; if (j < 0) j += 624;  | 
        ||
| 120 | v = (r->s[i] & ACC_UINT32L_C(0x80000000)) ^ (r->s[j] & ACC_UINT32L_C(0x7fffffff));  | 
        ||
| 121 | j = i - 227; if (j < 0) j += 624;  | 
        ||
| 122 | r->s[i] = r->s[j] ^ (v >> 1);  | 
        ||
| 123 | if (v & 1) r->s[i] ^= ACC_UINT32L_C(0x9908b0df);  | 
        ||
| 124 | } while (++i != 624);  | 
        ||
| 125 | }  | 
        ||
| 126 | v = r->s[r->n++];  | 
        ||
| 127 | v ^= v >> 11; v ^= (v & ACC_UINT32L_C(0x013a58ad)) << 7;  | 
        ||
| 128 | v ^= (v & ACC_UINT32L_C(0x0001df8c)) << 15; v ^= v >> 18;  | 
        ||
| 129 | return v;  | 
        ||
| 130 | }  | 
        ||
| 131 | |||
| 132 | |||
| 133 | /*  | 
        ||
| 134 | vi:ts=4:et  | 
        ||
| 135 | */  |