# How to generate random numbers in C

Discussion in 'C Programming' started by pereges, Apr 11, 2008.

1. ### peregesGuest

I need to generate two uniform random numbers between 0 and 1 in C ?
How to do it ?

I looked into rand function where you need to #define RAND_MAX as 1
but will this rand function give me uniformly distributed and unique
numbers ?

pereges, Apr 11, 2008

2. ### Ian CollinsGuest

Why would you attempt to redefine RAND_MAX? If you want random numbers
between 0 and 1, assign the value of rand() to a double or float and
divide by RAND_MAX.

The distribution of the numbers returned by rand() isn't the best.

Ian Collins, Apr 11, 2008

3. ### user923005Guest

If you have modern hardware and IEEE floating point, I recommend
dsfmt:
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html
otherwise WELL512a.c and WELL512a.h from here:
http://www.iro.umontreal.ca/~panneton/WELLRNG.html

Are another possibility.
That is a read-only value for you. It's not something that you set,
it is something that you inquire upon.

user923005, Apr 11, 2008
4. ### osmiumGuest

There is useful information in the FAQ starting at about 13.15

http://www.c-faq.com/lib/index.html

A set of numbers shouldn't be random AND unique. One of the important
properties of a random number generator is that numbers can be repeated. To
provide what I understand you to want, look into "shuffle" as described in
13.19

osmium, Apr 11, 2008
5. ### Richard TobinGuest

RAND_MAX tells you what the maximum random number is. It doesn't
let you control it.
rand() returns an integer between 0 and RAND_MAX. It's intended
to be uniformly distributed (though the standard doesn't seem to
say so) so you can get uniformly distributed random floating-point
numbers by something like

((double)rand()) / RAND_MAX

If you really need *unique* random numbers you're going to have to
do something more complicated. Are you sure you really do?

-- Richard

Richard Tobin, Apr 11, 2008

Because then the rand() values will be between 0 and 1 as desired!
That is a logical thought process for someone starting out.
That depends on quality of implementation.

7. ### Joachim SchmitzGuest

I don't find that logical at all. RAND_MAX is defined in a header that comes
part of the implementation, so why should anyone come to the idea it might
be possible to modify it with the result being a library funcion of that
implementation to behave different?
It should be faily obvious, that a macro is used at compile time and that
the library funktion has been compiled quite a while ago, so won't be able
to tell if a macro got changed afterwards.

Bye, Jojo

Joachim Schmitz, Apr 11, 2008
8. ### peregesGuest

what about drand48() function ? Is this included in C standard ?

pereges, Apr 11, 2008
9. ### Richard TobinGuest

[/QUOTE]
But why would a beginner know that?
Perhaps they read the description in the standard that says "The rand
function copmuters a sequence of pseudo-random integers in the range
0 to RAND_MAX".

Anyway, you have just seen an example of someone who made this mistake,
so it's clear that it can be misunderstood. Arguing that it shouldn't
be doesn't help anyone.

-- Richard

Richard Tobin, Apr 11, 2008
10. ### Joachim SchmitzGuest

But why would a beginner know that?[/QUOTE]
Because, (s)he'll find it on the disk after having install the compiler and
hasn't written this piece of code hime/herself. On a decently configured
system, using it as a non super user as it should be, (s)he even couldn't
make that modification due to file access permissions.
(And yes, I don't count Windows, up to XP at least, to this group, which
mostly requires you to work as Administrator or at least makes if very
difficult if you'r not)
True, and I did neither. I just claimed it illogical to understand it that
way.

Bye, Jojo

Joachim Schmitz, Apr 11, 2008
11. ### Joachim SchmitzGuest

Why not reading it yourself? At least the drafts are available at no charge,
the latest is to be found at
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

But no, drand48 is not mentioned there. I believe it is POSIX.

Bye, Jojo

Joachim Schmitz, Apr 11, 2008
12. ### Keith ThompsonGuest

We weren't talking about modifying the file ("stdlib.h" or whatever)
that contains the implementation's definition of RAND_MAX; a newbie
likely wouldn't even know where to find it. We were talking about
redefining the macro in user code.

It's easy to assume that this:

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
#undef RAND_MAX
#define RAND_MAX 10 /* No, this won't work */
int i;
for (i = 0; i < 10; i ++) {
printf("%d\n", rand());
}
return 0;
}

will produce numbers in the range 0 to 10. It could even be made to
work if rand() is a macro. In fact, since redefining RAND_MAX invokes
undefined behavior, it could be made to work in a conforming (but
perverse) implementation.

Keith Thompson, Apr 11, 2008
13. ### Paul HsiehGuest

http://www.pobox.com/~qed/random.html

Paul Hsieh, Apr 11, 2008
14. ### user923005Guest

The most important factor in gambling is the size of the house.
In a fair game, the player with the biggest house money volume wins.
Assuming a Markov process (random walk) the players will get ahead and
behind in a random, wobbling fashion. But as soon as the cash for one
player is gone, the game is over. If you have one hundred dollars and
the opponent has one trillion dollars, you are in a lot of trouble.
That's why I call gambling "A tax on stupidity." Of course if you
have a trillion dollars it's a good idea, but it isn't very nice in
that case.

There are PRNGs with a period so large it would not repeat if every
computer on earth ran it at full speed until the silicon wore out.
E.g. check out the period of the Mersenne Twister or WELL PRNGs.
Another problem is that it is not always possible to know if a seed is
poor or not. Zero is a typical PRNG buster.
The problem with these [0,1] and [0,1) PRNGs is that they are *very*
grainy. They only give approximately RAND_MAX distinct values. If
you want something that is uniform between 0 and 1, it is likely to be
problematic unless only a very low quality PRNG is needed.

user923005, Apr 11, 2008
15. ### Ian CollinsGuest

But rand() returns int.
OK, how about distribution of the numbers returned by rand() isn't
required to be the best.

Ian Collins, Apr 11, 2008
16. ### Walter RobersonGuest

I read a document describing the implementation of the electronic
games (e.g., slot machines) in a large real casino with many machines.
The numbers used were *not* true random numbers: they used a
complex algorithm that sent bursts of pseudo-random numbers to each
device, with the numbers sent out tweaked to dynamically alter the odds.
Thus when the central computer detected that a certain threshold of
money had come in, it would up the odds of winning so that there would
be a payout, to retain the long term house-odds they were licensed
to use by the appropriate gaming commission. Effectively, the casino
central computer would "pick" a machine have a jackpot on the basis
that it was time that -someone- won.

I do not recall now what was said about the manner in which the
pseudo-random bursts were generated; it was designed to make it
difficult to impossible for a human to predict, with the parameters
continually shifting. But the parameter shifts and numbers sent out
would be all carefully recorded to a write-once medium, so that if need
be afterwards the gaming commission or casino could examine the tapes
to ensure that the casino was not cheating the customers and that the
customers had not somehow cheated the casino.

Walter Roberson, Apr 11, 2008
17. ### user923005Guest

Right. It's about 30 cents per dollar, at least with one particular
lottery.
This Mersenne Twister only has 4 billion initial seeds:
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c
(although the internal state vector is actually much larger than
that).

But the WELL PRNGs take a list of 32 ints for the initial state
vector. For most architectures that will be 2^1024 initial states
possible.

In decimal, it's:
1797 69313 48623 15907 72930 51907 89024 73361 79769 78942
30657 27343 00811 57732 67580 55009 63132 70847 73224 07536
02112 01138 79871 39335 76587 89768 81441 66224 92847 43063
94741 24377 76789 34248 65485 27630 22196 01246 09411 94530
82952 08500 57688 38150 68234 24628 81473 91311 05408 27237
16335 05106 84586 29823 99472 45938 47971 63048 35356 32962
42241 37216
differnt states.
The Mersenne Twister and WELL PRNGs produce double values between 0
and 1 with the full mantissa populated. They are also faster than
most PRNGs distributed with C compilers.

user923005, Apr 12, 2008
18. ### Bill ReidGuest

There is no mathematical basis for this general statement, however,
there have been cases where people caught on to the sequence coming
from a poorly- or non-reseeded pseudo-random number generator
in a casino game and won hundreds of \$thousands before the
casino realized their error...
There is also no mathematical basis for THIS statement...you
guys are batting .000 again...
Oh, a "fair game"...who the hell offers a "fair game"? In any event,
it's irrelevant, because the actual most important factor (to the extent
that we indulge in the pointless semantics of pronouncing a "most
important factor") is the "expectation" of the game.
If you have a casino, and are stupidly offering a "fair game"
(0% "expectation"), you will eventually lose all your \$trillion
to salaries and other expenses no matter how many individual
players come in and lose \$100, because the money you win
from them will be offset by players who "get lucky" and win
\$100, \$200, \$3000, or more...

You would be correct if you asserted that there is relationship
as a fraction of that "bankroll" in terms of actually acheiving
a result of "bankroll" growth (or non-loss) that conforms to
your "expectation" for the game. But that's a slightly more
complicated concept, innit?
Stupidity is kind of its own tax, innit?

Bill Reid, Apr 12, 2008
19. ### Bill ReidGuest

I'll do you one better: I worked as a consultant for companies that
produced these types of machines, and was intimately familiar with
their technical operation...
This would be totally illegal under Nevada state law, and presumably,
almost certainly, most gaming venues.
Well, what you described would constitute de facto casino cheating
under Nevada state law...however, you are correct that a certain number
of game results are stored (but not necessarily in "write-once medium",
whatever that is), for various purposes, including checks by the
"Casino Control Commission" (or whatever it's called for the
particular venue).

Bill Reid, Apr 12, 2008
20. ### Ben BacarisseGuest

rnd(m) can be much closer to m than m-1. Did you mean:

#define rnd(x) ((int)((x) * uniform()))

perhaps? The OP wanted numbers between 0 and 1 so your uniform() is
sufficient if they mean doubles in [0,1).

Ben Bacarisse, Apr 12, 2008