Hi,
Following is the trimmed down version of the code I'm using to generate a set of random numbers using erand48
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
main()
{
unsigned short xsubi[3];
xsubi[0]=10;
double r;
int x[400];
int i=0, a=0, b=150;
r=erand48(xsubi);
x=floor(a + (b - a + 1)*r);
printf("%f\n", r);
}
I expect the code to print the same value for r every time, but it prints a different value! If I remove the line where the floor is calculated then I get the same value of r every time I run the code. Why should this happen? Does reading r somehow change something?
Thanks in advance for any insights you may have.
I get the same output every time I run it, but I'm not certain that's what you mean. I also note you're not seeding the RNG anywhere, so you shouldn't expect the RNG to be at any particular value on program startup. And I have no idea why you're putting the result of floor into the array like that, which will of course modify what values you get out of erand since that's where it stores its state!
It is common, in testing, to seed random generators with a constant for repeatability, and then in later testing and production, seed them with time() or fine time like from gettimeofday() or the like to make them vary randomly run by run.
Of course it is. I don't see that he's doing so.
erand48(3) - Linux man page
Well, since you are not seeding it, it might be more consistently unseeded if it was not on the stack picking up junk from prior calls. I think heap might be zeroed out.
Maybe just seed it with a constant or something from the env. for testing, and then seed it with time for more randomness, if desired. You need 6 bytes, and gettimeofday() provides 32 bit signed int time() plus 0-999999 microseconds, which feels like 41 bits.
@fpmurphy - Moving
unsigned short xsubi[3];
outside solves my problem!
Thanks for all replies. This is the first time i'm using erand48, but after reading the man page I felt that you do not need to call any of the seed functions and in effect you set the seed by initializing the Xi value. Doing
xsubi[0] = 10
I thought was achieving that, may be not filling all of the 48 bits, was an issue. I also tested this by initializing xsubi[0] to a different value and then I would get a new set of random numbers. All of this is what I wanted except that putting the floor call then somehow stopped giving me a consistent set of random numbers.
This might be a cause for worry. You could have buffer overflows and such that mangled its contents before, when it was on the stack, but won't now because it's a global variable, which get their own segment. But the mangling may still be happening.
If I initialize the entire array xsubi[3] I do not have to move its declaration outside main.
So I think having a huge array but not initializing it completely was having its contents over written which in effect was creating a new seed value. I don't know why the contents were being over written though.
That can be caused by things like buffer overruns.
Sure, I was wondering what was wrong in that isolated small piece of code that was causing buffer overflows..
I couldn't make that isolated scrap of code do what you were describing in the first place.
May be it's my compiler that's over optimizing space usage, I don't know. I've moved ahead.. but it sucks to not know where/how I was screwing up.
Out of curiosity, what platform, OS and compiler were you using?
It's the standard stuff. Ubuntu 8.04, Linux kernel version 2.6.24-28. gcc version 4.2.3