15

How do I generate a random number between 0 and 1?

Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
tm1
  • 211
  • 1
  • 3
  • 6
  • 5
    Truly random or pseudorandom? – tvanfosson Mar 07 '10 at 14:31
  • @tm1 -- Pseudorandom numbers only approximate the properties of random numbers and won't necessarily be suitable for applications that require real randomness, like cryptography. See http://en.wikipedia.org/wiki/Pseudorandom_number_generator for an explanation. – tvanfosson Mar 07 '10 at 14:35
  • Another article that may be of interest: http://en.wikipedia.org/wiki//dev/random – tvanfosson Mar 07 '10 at 14:41
  • `function getRandom() { return 0.4; } // chosen by fair dice roll. guaranteed to be random.` – kennytm Mar 07 '10 at 15:11
  • @KennyTM You have dice with sides that can sum to every real number between 0 and 1? Impressive. – Tyler McHenry Mar 07 '10 at 15:24
  • My fair die has 6 sides, all has 0.4 written on it. – kennytm Mar 07 '10 at 15:39
  • @Tyler: I'm pretty confident that the questioner does not need the output to be capable of outputting *any* real number between 0 and 1. At least not if the program is supposed to terminate. pi/4? e/3? – Steve Jessop Mar 07 '10 at 15:52
  • 2
    duplicate many times over: http://stackoverflow.com/questions/1190870/i-need-to-generate-random-numbers-in-c-closed http://stackoverflow.com/questions/822323/how-to-generate-a-random-number-in-c http://stackoverflow.com/questions/1167253/implementation-of-rand and others. BTW, @tm1, I found that with this search http://stackoverflow.com/search?q=[c]+random+number . – dmckee --- ex-moderator kitten Mar 07 '10 at 21:10
  • @dmckee: It seems the ones that you quote here all generate random integers. Your search does include http://stackoverflow.com/questions/1694827/random-float-number-help , which is more relevant. – MSalters Mar 08 '10 at 13:58
  • @N1.1 Strictly speaking it shouldn't matter :) – Alexei Averchenko Sep 09 '12 at 11:17

3 Answers3

22

You can generate a pseudorandom number using stdlib.h. Simply include stdlib, then call

double random_number = rand() / (double)RAND_MAX;
Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
  • 2
    For reference, this will give values in [0.0, 1.0] i.e. including both 0.0 and 1.0. – Philip Potter Mar 07 '10 at 15:42
  • 3
    And most importantly, it will most likely not be fair (!) There are many implementations where the set [0.0, 1.0] contains more than RAND_MAX elements. (_In C, the set [0.0, 1.0] is a countable finite set_) – MSalters Mar 08 '10 at 14:02
  • @MSalters, that's an interesting problem, any thoughts on a solution? – Mark Elliot Mar 08 '10 at 15:13
  • 1
    it really depends on the application. The first thing to realize is that the set `[0.00, 0.01]` contains many more elements than the set `[0.99, 1.00]`. This is because `1E-100 > 0` but `1 - 1E-100 == 1`. For many applications this can be counteracted by setting `p(x) = 1.0/(_nextafter(x)-x);` although this technically works for the range `[0.0, 1.0)`. The result is that p(x) depends on x, but `SUM[0<=i – MSalters Mar 08 '10 at 15:36
  • 1
    Oh, and often it just doesn't matter - many applications would work even with `double arr[11] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 }; return arr[rand % 11];` – MSalters Mar 08 '10 at 15:38
9

Assuming OP wants either 0 or 1:

srand(time(NULL));
foo = rand() & 1;

Edit inspired by comment: Old rand() implementations had a flaw - lower-order bits had much shorter periods than higher-order bits so use of low-order bit for such implementations isn't good. If you know your rand() implementation suffers from this flaw, use high-order bit, like this:

foo = rand() >> (sizeof(int)*8-1)

assuming regular 8-bits-per-byte architectures

qrdl
  • 34,062
  • 14
  • 56
  • 86
  • 1
    you should shift the result of `rand()` to account for problems with linear congruential generators – Christoph Mar 07 '10 at 14:52
  • @Christoph Thank you, I've edited my post to reflect your point. – qrdl Mar 07 '10 at 15:07
  • 6
    Who said `rand()` uses all 32 bits? `RAND_MAX` on MSVC is 0x7fff, for instance (http://msdn.microsoft.com/en-us/library/2dfe3bzd%28VS.80%29.aspx). – kennytm Mar 07 '10 at 15:13
  • 2
    you don't have to assume 8-bits-per-byte if you use `rand() >> (sizeof(int)*CHAR_BIT-1)`. – Philip Potter Mar 07 '10 at 15:43
  • use an arbitrary shift `(rand() >> RAND_SHIFT) & 1` and check at compile-time that `RAND_MAX > (1 << RAND_SHIFT)`; alternatively, if `RAND_MAX` is of form `2^n - 1`, you can use `rand() / ((RAND_MAX + 1) >> 1)` to get the most significant bit; you can again check this at compile-time via `(RAND_MAX & (RAND_MAX + 1)) == 0` – Christoph Mar 07 '10 at 17:14
  • You can always use `rand() / (RAND_MAX + 1)` to get a single random bit, independent of the exact value of `RAND_MAX`. This could be slightly unfair if RAND_MAX is even, though. Easiest to see if you assume RAND_MAX is 2: `rand()` would generate either 0, 1 or 2. It's impossible to extract a single unbiased random bit from that. – MSalters Mar 08 '10 at 14:08
  • 1
    @MSalters: Won't you always get 0 with `rand() / (RAND_MAX + 1)`? – kennytm Mar 08 '10 at 18:45
8

man 3 drand48 is exactly what you asked for.

The drand48() and erand48() functions return non-negative, double-precision, floating-point values, uniformly distributed over the interval [0.0 , 1.0].

These are found in #include <stdlib.h> on UNIX platforms. They're not in ANSI C, though, so (for example) you won't find them on Windows unless you bring your own implementation (e.g. LibGW32C).

ephemient
  • 198,619
  • 38
  • 280
  • 391