Random Accuracy

Because I'm using Neural Networks I need to generate accurate random numbers between 0 -> X. For that I tried to use rand function but I noticed that the generated numbers loose their accuracy whenever I increase X

I used the following code for generating numbers between 0->1000000

1
2
3
4
double getRand(double m)
{
    return ((double)m*rand()/(RAND_MAX+1.0));
}


To preview the resultant numbers see the following picture:
http://img215.imageshack.us/img215/9721/screenshotmainwindow.png

I've read many posts and articles about this problem but I couldn't find any real solution for it in C++ so I tried to fix this issue by increasing RAND_MAX range but it didn't give me any satisfied results.
By the end I tried another programming languages such as Borland Delphi and I discovered that Delphi generates accurate random number as I want as shown in the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure TForm1.btn1Click(Sender: TObject);

var

  I: Integer;

begin

  Randomize;

  lst1.Clear;

  for I := 0 to 10 do

    lst1.Items.Add(FloatToStr(Random*1000000))

end;


To preview the resultant numbers see the following picture:
http://img228.imageshack.us/img228/1299/screenshotform1.png
Last edited on
generated numbers loose their accuracy
What is that supposed to mean? How can a number be inaccurate?

increasing RAND_MAX
That won't do anything but throw off your own computations.

There's two things you can do. The first is kinda cheap, not portable, and I'm not sure it works very well:
1
2
3
4
//Generate 32 random bits
unsigned rnd32(){
    return rand()|(rand()<<15)|(rand()<<30);
}


The second is: Google Mersenne Twister
You don't get much better than that.
Last edited on
What is that supposed to mean? How can a number be inaccurate?

If you saw the picture you'll notice that C++ generated numbers are nearly integers where in Delphi are still floats. This is what I meant in accuracy. For me this is important point because:

*) when I generated numbers between 0->10 in C++ I got numbers with comma and 4 numbers after (ex. 5.7835) while in Delphi I got 12 numbers after the comma (3.640074264945)
*) for 0->1000 in C++ I got 3 numbers after comma while in Delphi I got 11!
*) for 0->100000 in C++ I got 1 number after comma while in Delphi I got 10!
*) for 0->1000000 in C++ I got integers while in Delphi I got floats with 9 numbers after comma!


he first is kinda cheap, not portable, and I'm not sure it works very well
1
2
3
4
//Generate 32 random bits
unsigned rnd32(){
    return rand()|(rand()<<15)|(rand()<<30);
}

For me, it's working but it gave me integers. How I can get doubles?

The second is: Google Mersenne Twister
You don't get much better than that.

Actually, I didn't hear about before so I'll make some researches about it.
In mean time if you know any way for creating random doubles such as Delphi's way could you please tell me about it?

Thanks for advance.
when I generated numbers between 0->10 in C++ I got numbers with comma and 4 numbers after (ex. 5.7835) while in Delphi I got 12 numbers after the comma (3.640074264945)
Don't trust the output.

For me, it's working but it gave me integers. How I can get doubles?
Convert return value to double, divide by 4294967296.0 (2^32). That gives a number in the range [0;1).
Convert return value to double, divide by 4294967296.0 (2^32). That gives a number in the range [0;1).

I tried the following but it gave me integers!
1
2
3
4
double rnd32_double(double m)
{
    return m*((rand()|(rand()<<15)|(rand()<<30))/4294967296.0);
}
You didn't convert to double first. The compiler is converting the right-hand operand to integer, I believe.
1
2
3
4
double rnd32_double(double m)
{
    return double(rand()|(rand()<<15)|(rand()<<30))/4294967296.0*m;
}
You didn't convert to double first

I got same result. Any way I'm making researches about Mersenne Twister to see if I can get double random number with large numbers after comma such as: 35464.5015455
1
2
3
double rnd32(double m){
	return double(unsigned(rand()|(rand()<<15)|(rand()<<30)))/4294967296.0*m;
}

It's working fine for me.
m=100:
46.501
68.7109
50.0859
40.4045
9.56923
64.5287
42.6511
85.0816
75.1154
9.62262
It's working fine for me.

what about m=1000000! it will not work fine because it will works just like first snippet I've posted
1
2
3
4
double getRand(double m)
{
    return ((double)m*rand()/(RAND_MAX+1.0));
}
I told you. Don't trust the output.
With std::cout <<std::setprecision(20); added:
727143.53236369789
489118.8689507544
613189.64348174632
491247.57293611765
39336.910471320152
183319.13347356021
24504.142580553889
190673.56898449361
498735.22412963212
596522.43228629231


Why don't people ever listen?
Last edited on
I told you. Don't trust the output.

You are absolutely right thanks.

And I want to thank you again for Mersenne Twister, I found the following nice library which is used Mersenne Twister:
http://www.agner.org/random/
Topic archived. No new replies allowed.