系统自带的随机数函数rand()得到的随机数不是很好,项目中需要自定义一个方法
CustomRand.h头文件
#ifndef _CUSTOM_RAND_H_
#define _CUSTOM_RAND_H_
void g_random_set_seed(unsigned long seed);
unsigned long g_random_int(void);
unsigned long g_random_int_range(unsigned long begin,unsigned long end);
#endif
CustomRand.cpp源文件
#include "stdafx.h"
#include "CustomRand.h"
/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0df /* constant vector a */
#define UPPER_MASK 0x80000000 /* most significant w-r bits */
#define LOWER_MASK 0x7fffffff /* least significant r bits */
/* Tempering parameters */
#define TEMPERING_MASK_B 0x9d2c5680
#define TEMPERING_MASK_C 0xefc60000
#define TEMPERING_SHIFT_U(y) (y >> 11)
#define TEMPERING_SHIFT_S(y) (y << 7)
#define TEMPERING_SHIFT_T(y) (y << 15)
#define TEMPERING_SHIFT_L(y) (y >> 18)
struct GRand
{
unsigned long mt[N]; /* the array for the state vector */
unsigned long mti;
};
GRand __grand;
void g_rand_set_seed (GRand* rand, unsigned long seed)
{
#if 0
switch (get_random_version ())
{
case 20:
/* setting initial seeds to mt[N] using */
/* the generator Line 25 of Table 1 in */
/* [KNUTH 1981, The Art of Computer Programming */
/* Vol. 2 (2nd Ed.), pp102] */
if (seed == 0) /* This would make the PRNG produce only zeros */
seed = 0x6b842128; /* Just set it to another number */
rand->mt[0]= seed;
for (rand->mti=1; rand->mti<N; rand->mti++)
rand->mt[rand->mti] = (69069 * rand->mt[rand->mti-1]);
break;
case 22:
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous version (see above), MSBs of the */
/* seed affect only MSBs of the array mt[]. */
rand->mt[0]= seed;
for (rand->mti=1; rand->mti<N; rand->mti++)
rand->mt[rand->mti] = 1812433253UL *
(rand->mt[rand->mti-1] ^ (rand->mt[rand->mti-1] >> 30)) + rand->mti;
break;
default:
}
#endif
rand->mt[0]= seed;
for (rand->mti=1; rand->mti<N; rand->mti++)
rand->mt[rand->mti] = 1812433253UL * (rand->mt[rand->mti-1] ^ (rand->mt[rand->mti-1] >> 30)) + rand->mti;
}
unsigned long g_rand_int (GRand *rand)
{
unsigned long y;
static const unsigned long mag01[2]={0x0, MATRIX_A};
/* mag01[x] = x * MATRIX_A for x=0,1 */
if (rand->mti >= N) { /* generate N words at one time */
int kk;
for (kk = 0; kk < N - M; kk++) {
y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
rand->mt[kk] = rand->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
}
for (; kk < N - 1; kk++) {
y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
rand->mt[kk] = rand->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
}
y = (rand->mt[N-1]&UPPER_MASK)|(rand->mt[0]&LOWER_MASK);
rand->mt[N-1] = rand->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
rand->mti = 0;
}
y = rand->mt[rand->mti++];
y ^= TEMPERING_SHIFT_U(y);
y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
y ^= TEMPERING_SHIFT_L(y);
return y;
}
unsigned long g_rand_int_range (GRand *rand, unsigned long begin, unsigned long end)
{
unsigned long dist = end - begin;
unsigned long random;
#if 0
switch (get_random_version ())
{
case 20:
if (dist <= 0x10000L) /* 2^16 */
{
/* This method, which only calls g_rand_int once is only good
* for (end - begin) <= 2^16, because we only have 32 bits set
* from the one call to g_rand_int ().
*
* We are using (trans + trans * trans), because g_rand_int only
* covers [0..2^32-1] and thus g_rand_int * trans only covers
* [0..1-2^-32], but the biggest double < 1 is 1-2^-52.
*/
gdouble double_rand = g_rand_int (rand) *
(G_RAND_DOUBLE_TRANSFORM +
G_RAND_DOUBLE_TRANSFORM * G_RAND_DOUBLE_TRANSFORM);
random = (unsigned long) (double_rand * dist);
}
else
{
/* Now we use g_rand_double_range (), which will set 52 bits
* for us, so that it is safe to round and still get a decent
* distribution
*/
random = (unsigned long) g_rand_double_range (rand, 0, dist);
}
break;
case 22:
if (dist == 0)
random = 0;
else
{
/* maxvalue is set to the predecessor of the greatest
* multiple of dist less or equal 2^32.
*/
guint32 maxvalue;
if (dist <= 0x80000000u) /* 2^31 */
{
/* maxvalue = 2^32 - 1 - (2^32 % dist) */
guint32 leftover = (0x80000000u % dist) * 2;
if (leftover >= dist) leftover -= dist;
maxvalue = 0xffffffffu - leftover;
}
else
maxvalue = dist - 1;
do
random = g_rand_int (rand);
while (random > maxvalue);
random %= dist;
}
break;
default:
random = 0; /* Quiet GCC */
g_assert_not_reached ();
}
#else
if (dist == 0)
{
random = 0;
}
else
{
/* maxvalue is set to the predecessor of the greatest
* multiple of dist less or equal 2^32.
*/
unsigned long maxvalue;
if (dist <= 0x80000000u) /* 2^31 */
{
/* maxvalue = 2^32 - 1 - (2^32 % dist) */
unsigned long leftover = (0x80000000u % dist) * 2;
if (leftover >= dist) leftover -= dist;
maxvalue = 0xffffffffu - leftover;
}
else
maxvalue = dist - 1;
do
random = g_rand_int (rand);
while (random > maxvalue);
random %= dist;
}
#endif
return begin + random;
}
void g_random_set_seed(unsigned long seed)
{
g_rand_set_seed (&__grand, seed);
}
unsigned long g_random_int(void)
{
return g_rand_int(&__grand);
}
unsigned long g_random_int_range(unsigned long begin,unsigned long end)
{
return g_rand_int_range(&__grand, begin, end);
}
用法:
g_random_set_seed(time(NULL));
BYTE cbSiceBig = g_random_int()%6+1;