1

Possible Duplicate:
How to generate a random float between 0 and 1?

I want to generate a random number between 0 and 1 (uniform distribution) and I use:

float x = arc4random_uniform(1);

However, this produces only 0.00000

I used

float y = arc4random() %11 * 0.1;

which returns a random number in the interval but I am not sure if it is uniform distribution.

Why isn't the first function working as expected?

Community
  • 1
  • 1

4 Answers4

5

I use:

float x = arc4random_uniform(1);

However, this produces only 0.00000

Of course it does. arc4random_uniform() returns a 32-bit unsigned integer. It does not return a float. What you're looking for is something like

#define RAND_PRECISION 1024

float x = arc4random_uniform(RAND_PRECISION) / (float)RAND_PRECISION;

Also,

I am not sure if it is uniform distribution.

Since it isn't. Using the modulo (%) operator results in a non-uniform distribution.

  • Note that there's no way to give a truely uniform distribution on a floating point interval except one roughly of the form `[N,2N-N*FLT_EPSILON]` since, in general, floating point values are not uniformly spaced. – R.. GitHub STOP HELPING ICE Nov 28 '12 at 18:32
  • @R.. Of course, that's why I called the divisor `PRECISION`... –  Nov 28 '12 at 18:37
  • I did not downvote, but if your constant RAND_PRECISION was a power of two less than 2^23 (give or take a factor of 2, I am terrible at this particular kind of fencepost problem), your formula would at least give equiprobable evenly spaced values. Also, a compiler that tries to compile floating-point in a standard-conforming way has no choice but to compile `/ RAND_PRECISION` to a floating-point division. If it was a power of two, that could be optimized into a multiplication. Lastly, multiplying by `1.0f` is a strange way to convert an `int` to `float` (but the compiler should optimize it). – Pascal Cuoq Nov 28 '12 at 23:12
  • "I am terrible at this particular kind of fencepost problem" - I understand you. Mee too. Anyways, good suggestions and updated my answer accordingly, but that cast is really ugly. –  Nov 28 '12 at 23:15
  • @PascalCuoq: They're not even evenly spaced unless `RAND_PRECISION` is a power of two. – R.. GitHub STOP HELPING ICE Nov 28 '12 at 23:51
  • @R.. Yes, that is definitely what my first sentence was intended to mean. – Pascal Cuoq Nov 29 '12 at 00:34
2

According to the documentation, arc4random_uniform returns an integer, so using it with an upper bound of 1 won't produce what you want.

Here's the page on the arc4random functions: http://www.unix.com/man-page/FreeBSD/3/arc4random_uniform/

RonaldBarzell
  • 3,822
  • 1
  • 16
  • 23
0
#define ARC4RANDOM_MAX      0x100000000
...
double val = ((double)arc4random() / ARC4RANDOM_MAX);
Mohammad Rabi
  • 1,412
  • 2
  • 21
  • 41
0

arc4random_uniform returns a number up to the upper bound you provide (e.g. arc4random_uniform(10) will return a number between 0 and 9). Due to that arc4random_uniform(1) should always return 0 (which is what you're seeing). If you want a random float you should see this answer:

Generate a random float between 0 and 1

Community
  • 1
  • 1
Mattia
  • 2,251
  • 1
  • 22
  • 27