1

I am more than likely doing this whole code wrong, but when attempting the find the range of:

4.0*rand()/RAND_MAX + 1

I end up only getting the number 0 as a result, and I'm pretty sure there's more to it than that.

Code (in C):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


int main()
{
srand(time(NULL));

 int r;
 4.0*rand()/RAND_MAX+1;
 printf("%i",r);

return 0;
}
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
EJ A
  • 7
  • 1

2 Answers2

1

double rr = 4.0*rand()/RAND_MAX+1; You need to use a double and more importantly assign the result (rr) to some variable.

printf("%lf",rr); For printing the result.

As far as it is seen there is no range calculation here.

You are simply printing an uninitialized variable(r). (which seems to comtain the value 0 when you printed).

user2736738
  • 30,591
  • 5
  • 42
  • 56
  • Everything except the `.0` after the `4` suggests that what is intended is integer math. Needless to say that using doubles will give a very different distribution compared to working with integers; not to mention the difficulty in attempting an actual accounting of the real distribution when using doubles, which you wisely do not attempt. – Patrick87 Nov 28 '17 at 16:15
  • @Patrick87.: Please don't mind but would you clarify a bit? The distribution would be different here the range would be infinite but if we think this way that whatever be the number now we will consider the integral part of the double then yes this is workable. Or correct me if I am wrong? – user2736738 Nov 28 '17 at 16:20
  • No trouble - the distribution will be a discrete distribution with `RAND_MAX+1` possible outcomes. The spacing will be a little uneven due to truncation but there shouldn't be a problem with duplicates and degrading spacing provided RAND_MAX is a 32-bit integer and we're talking about doubles. Using this formula and then keeping the integer part will produce exactly the same distribution as integer-only code, under the same assumptions. – Patrick87 Nov 28 '17 at 18:34
  • @Patrick87.: I don't know why OP asked the question like this. I mean maybe some experiment of OP's own. Otherwise I dont know. I just concentrated on the part of that yes there is an assignment problem and if it is being done there will be no truncation due to int arithmetic. Thanks for stopping by and explaining. – user2736738 Nov 28 '17 at 18:37
0

Two things:

First, you are never assigning r any value. You need to change 4.0*rand()/RAND_MAX+1; to r = 4.0*rand()/RAND_MAX+1;

Second, the compiler will likely complain about that since you're degrading from double to int. You should change 4.0 to 4.

The final code should look roughly like r = 4*rand()/RAND_MAX+1;. Then, the range will be {1, 2, 3, 4, 5} (note: depends on whether rand can return RAND_MAX or only less than RAND_MAX. If only less, then exclude 5.) If you wanted {0, 1, 2, 3} you needed to enclose RAND_MAX+1 in parentheses.

Note: as pointed out in the comments, there may be some concerns with the above. You can use something like this to get exactly the same distribution:

r = rand()
if (r == RAND_MAX) return 5;
else return r % 4 + 1;

If you don't ever want to return 5, you can use rejection sampling:

r = RAND_MAX;
while (r == RAND_MAX) r = rand();
return r % 4 + 1;
Patrick87
  • 27,682
  • 3
  • 38
  • 73
  • 1
    But wouldn't `rand()/RAND_MAX` be `0`? It's integral math. – user2736738 Nov 28 '17 at 15:44
  • @coderredoc Yes (if `rand` cannot return `RAND_MAX`, which I don't remember, but I will grant) but `4*rand()/RAND_MAX` can return non-zero numbers since`4*rand()` should be evaluated first. – Patrick87 Nov 28 '17 at 15:46
  • 1
    `4 * rand()` Could overflow if RAND_MAX is INT_MAX – Bob__ Nov 28 '17 at 15:48
  • @Bob__ Fair point; the value of RAND_MAX is implementation dependent. This would need to be checked. It looks like it's 32,767 (the minimum guaranteed value) in my environment, so it would be fine. – Patrick87 Nov 28 '17 at 15:52
  • 1
    `rand()` can return `RAND_MAX`. – chux - Reinstate Monica Nov 28 '17 at 15:52
  • BTW: In one of my environments, `RAND_MAX == 32767` and `4*RAND_MAX` overflows. – chux - Reinstate Monica Nov 28 '17 at 15:53
  • Also suppose the `rand()` return something less than `RAND_MAX/4` here it will give `0` result for it, There is `25%` chance there will be `1` as a result. – user2736738 Nov 28 '17 at 15:55
  • @coderredoc Right, if rand returns something less than RAND_MAX/4, then 4*rand()/RAND_MAX+1 will be 1, and that has probability 25%. – Patrick87 Nov 28 '17 at 16:00
  • Sorry, but your last edit doesn't make much sense (to me, at least). Are you trying to do something like this: https://stackoverflow.com/a/29371056/4944425 (or https://stackoverflow.com/a/2129979/4944425 ) instead of the *"canonical"* `int rnd_number_between_1_and_6 = rand() % 6 + 1;`? – Bob__ Nov 28 '17 at 16:59
  • @Bob__ What part is confusing? In particular, the `r % 4 + 1` part is very similar to the example you give. The rest of it has to do with handling the case where `rand` returns `RAND_MAX`, which is the only case where the result 5 is possible. – Patrick87 Nov 28 '17 at 17:16
  • @Bob__ I am not sure what those are meant to be doing, possibly because there are no comments or indications of the author's intent. I can guess based on what I see the code is doing; for instance, `rnd_1` generates a number more-or-less uniformly at random between `min` and `min + max - 1`; `rnd_2` between `min` and `min + max - 2`; and `rnd_3` the same. It appears this code breaks if you try to test `Min > 1`. I'm not sure why you'd want to use this code and it is not what I was aiming for, based on a plain reading of what it's doing. – Patrick87 Nov 28 '17 at 18:18
  • Yeah, that was bugged. [Here](https://ideone.com/dq3ZbY) is fixed. The point is that in your snippet you return the max value (5) only 1/RAND_MAX times, while it should be 1/5 (every value the same probability) if you want to include that value. – Bob__ Nov 28 '17 at 19:06
  • @Bob__ But the OP's code - or at least the interpretation thereof given in my answer - *does* generate 5 with probability 1/RAND_MAX. That is what I am trying to match. – Patrick87 Nov 28 '17 at 19:24