[go: up one dir, main page]

File: rand.ch

package info (click to toggle)
ucl 1.03-3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 4,884 kB
  • ctags: 9,973
  • sloc: sh: 11,725; asm: 10,461; ansic: 5,057; makefile: 137
file content (135 lines) | stat: -rw-r--r-- 3,628 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* ACC -- Automatic Compiler Configuration

   Copyright (C) 1996-2004 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/
 */


#define __ACCLIB_RAND_CH_INCLUDED 1
#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 /* 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;
#if (SIZEOF_ACC_INT64L_T > 8)
    r->seed &= ACC_UINT64L_C(0xffffffffffffffff);
#endif
    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;
#if (SIZEOF_ACC_INT64L_T > 8)
    r->seed &= ACC_UINT64L_C(0xffffffffffffffff);
#endif
    return (acc_uint32l_t) (r->seed >> 32);
}

#endif /* 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 = 0;
        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
*/