Tatu Portin said:
I need a pseudorandom algorithm that produces same results with same
seed across different platforms. I'm not sure, but I think that
standard rand() does produce different set of numbers on different
platforms. I would be using only four distinct values,
i.e. (rand() % 4).
This algorithm would be used to generate a bitmap when a game starts,
and if randomness is platform-variable, the game will look different
on different platforms and this is not what I want.
/***** This file is prand32.h *****/
#ifndef H_PRAND32_H
#define H_PRAND32_H
/**************************************************************************/
/* A portable, platform independent, pseudo-random number generator. */
/* */
/* random_32() yields a 32-bit, uniformly distributed, "random number". */
/* */
/* Use seed_random_32() to supply a 32-bit seed value for random_32(). */
/**************************************************************************/
#define random_32() (*--random_32_p ? *random_32_p : cycle_random_32())
extern void seed_random_32( unsigned long );
extern unsigned long (random_32)( void );
/*************************/
/* for internal use only */
/*************************/
extern unsigned long cycle_random_32( void );
extern const unsigned long *random_32_p;
#endif /* H_PRAND_H */
/***** End of prand32.h *****/
/***** This file is prand32.c *****/
#include "prand32.h"
/***********************************************************/
/* The method employed is based on a lagged fibonacci PRNG */
/* given in Knuth's "Graph Base" book. */
/***********************************************************/
#define VALUES_N (55u)
#define VALUES_D (24u)
/* Other reasonable values: 33,20 17,11 9,5 */
#define VALUES_INDEX_LIMIT (VALUES_N + 1)
static unsigned long values[VALUES_INDEX_LIMIT];
const unsigned long *random_32_p = values + VALUES_INDEX_LIMIT;
static const unsigned long mask32 = 0xffffffffUL;
void
seed_random_32( unsigned long seed_value ){
unsigned i;
values[1] = seed_value & mask32;
for( i = 2; i < VALUES_INDEX_LIMIT; i++ ) values
= 0;
for( i = 0; i < VALUES_INDEX_LIMIT * 2; i++ ){
random_32_p = &values[0];
(void) cycle_random_32();
}
}
unsigned long
(random_32)( void ){
return random_32();
}
unsigned long
cycle_random_32(){
unsigned i;
if( random_32_p == &values[0] ){
for( i = 1; i + VALUES_D < VALUES_INDEX_LIMIT; i++ ){
values -= values[ i+VALUES_D ];
values &= mask32;
}
for( i = i; i < VALUES_INDEX_LIMIT; i++ ){
values -= values[ i - (VALUES_N - VALUES_D) ];
values &= mask32;
}
for( i = 1; i < VALUES_INDEX_LIMIT; i++ ){
values ^= (mask32 ^ values[i-1]) >> 1;
}
random_32_p = &values[VALUES_INDEX_LIMIT - 1];
} else if( random_32_p == &values[VALUES_INDEX_LIMIT - 1] ){
seed_random_32( 0 );
}
return *random_32_p;
}
/***** End of prand32.c *****/
Query to comp.lang.c readers: What platform dependencies
did I miss?