I have two problems, I am using c++ in visual studio for windows. I am making a random number generator as a class to be used with various projects of mine. Only using it in one program so far though.
First problem, 75% of all the generated numbers are in the lowest 20% of the range. ( I am trying to get a range evenly from -a to a, by "random number %(a*2)-a" )
the built in generator in <random> was giving me this problem so I found a better generator, the one below,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
The following xorshift+ generator, is a variation with 128 bits of state, a maximal period of 2128 − 1[8] and passes BigCrush:
This generator is one of the fastest generator passing BigCrush;[4] however, it is only 1-dimensionally equidistributed.
#include <stdint.h>
/* The state must be seeded so that it is not everywhere zero. */
uint64_t s[2];
uint64_t xorshift128plus(void) {
uint64_t x = s[0];
uint64_t const y = s[1];
s[0] = y;
x ^= x << 23; // a
x ^= x >> 17; // b
x ^= y ^ (y >> 26); // c
s[1] = x;
return x + y;
}
|
I still have the exact same problem, so I figure it must be how I am using it.
(Also, a side question, I haven't been able to find out what x ^= y does. I did figure out that using << or >> does something with shifting bits but I don't really understand that. If someone could explain what this generator is doing and how would be appreciated.)
So back to the primary issue,
the code I'm using,
location is a type that holds three doubles with some comparison functions. represents 3d coordinates.
lrand is my random function that takes a range and return a value between 0 and range parameter as a double
newLoca is a function that checks the input location against a list of current locations to ensure none are within a distance of the second parameter and returns a bool value of whether the new location was too close to an existing location.
mL is the range limit (stands for map limit)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
lrand(int range){
double X = (rn.rnd());//returns a random number from the above code
unsigned long long Y = X;// makes it an integral type
X = Y % range;//limits to range
return X;
}//close lrand
do{
location trip2(
lrand(mL * 2) - mL, //each parameter
lrand(mL * 2) - mL,
lrand(mL * 2) - mL);// make a new location
if (!newLoca(trip2, 10)){ //checks to prevent clipping objects,
err.rep("mapstream", "eShell", 228, "newLocation was bad");//error callout if new location would clip another, not needed but fun for the moment
continue;//restart in the case of a bad location
}//close if
} while (iter>0);
|
So I primarily need this to have objects evenly spaced across the available environment and not in the bottom fifth.
return results from this generator,
range limit, -150000 to 150000
highest result, 149904
lowest result, -149680
breakdown of result range by fifths for one run through
0% - 20%: 350 results
20% - 40%: 62 results
40% - 60%: 66 results
60% - 80%: 53 results
80% - 100%: 57 results
edit: not sure why I get these results, but when I examine the locations in a 3d environment they actually appear evenly distributed.