0

How can I generate random numbers from 0 to 1000000?

I already tried the code below, but it still gives me numbers from 0 to 32767 (RAND_MAX):

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

int main(){
    int i,x;
    srand(time(NULL));
    for(i=0; i<10000; i++){
        int x = rand() % 10000000 + 1;
        printf("%d\n",x);
    }
    return 0;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Roni Castro
  • 1,968
  • 21
  • 40

3 Answers3

5

[Edit] The initial answer was for 0 to 1,000,000. I now see it should be 0 to 10,000,000.

As rand() will give an answer of at least 15 bits, call rand() multiple times, shift by 15 and XOR the results. Finally mod by 10,000,001.

unsigned long x;
x = rand();
x <<= 15;
x ^= rand();
x %= 10000001;

The distribution is very flat, but does introduce a very small bias. After 32768*32768 iterations, each value of x 0 to 10,000,000 to occur about 107.37 times. Instead they range from 107 to 108 times.

Combining multiple rand() call results with +, * or | will cause a significant bias in the distribution of the results.

[Edit]

RAND_MAX is 32767 (0x7FFF) for OP's platform. The C spec says "value of the RAND_MAX macro shall be at least 32767". Because RAND_MAX may be longer than 15 bits, it is important to use the ^ operator above rather than | for this code when used on other platforms.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
2

Calculate with % 1000001 if you want numbers between 0 and 1000000. Also RAND_MAX is conly guaranteed to be at least 32767

int main(){
  int i, x;
  srand(time(NULL));
  for(i=0; i<10000; i++){
    x = (rand() * rand()) % 1000001;
    printf("%d\n",x);
  }
  return 0;
}
Constantin
  • 8,721
  • 13
  • 75
  • 126
  • 1
    @Jongware RAND_MAX is guaranteed to be 32767 - so `32767 * 32767 = 1073676289` should be sufficient – Constantin Nov 08 '13 at 23:27
  • 1
    Ta, just noticed the tweak in your code that evades it. Sorry. Aren't there any side effects to multiplying? Personally, I'd rather use XOR and a shift -- Maybe I should compare these two methods. – Jongware Nov 08 '13 at 23:29
  • alternatively: ( rand() + rand() + rand() + rand() ) % 100000; – Andrew - OpenGeoCode Nov 08 '13 at 23:31
  • 5
    @Constantin Won't you miss all prime numbers above RAND_MAX by factoring two rand() results? If my poor maths skills are right, you will not get all numbers back in the sequence. – thst Nov 08 '13 at 23:32
  • @thst: ooh excellent! That must have been nagging me in the back in my mind (way, way back). – Jongware Nov 08 '13 at 23:34
  • @Jongware There should be no noticeable side effect - most likely a strange probability distribution could happen: just like thst mentioned – Constantin Nov 08 '13 at 23:34
  • 1
    @Constantin: thst is right but not for the reason you think. Using multiplication, there is no way you can get 32771. – Jongware Nov 08 '13 at 23:37
  • @Jongware Yes, I'm aware of prime numbers. But you can still get 32771: imagine one rand() call equals to 19861 and the other one to 52 – Constantin Nov 08 '13 at 23:42
  • 1
    @Constantin: (cough-blush) okay, there is a hidden sublety there. Let's find out who falls *next* for the "obviously wrong" answer ... (I did, then decided to think it tru'). – Jongware Nov 08 '13 at 23:46
  • 1
    (rand() | (rand()<<15)) should be sufficient – technosaurus Nov 09 '13 at 00:52
  • @technosaurus `(rand() ^ (rand()<<15))` would be better (^ vs. |). – chux - Reinstate Monica Nov 09 '13 at 04:46
  • 2
    @Jongware I'll take the shot and assert "obviously poor answer". Calling rand() twice is like 2 32768 sided dice with 32768*32768 combinations. The product modded by 1000001 comes up with distribution most uneven. The average occurrence should be ~1074, but 0 comes up 67479 times and 896370 comes up only 800 (the worst) times. – chux - Reinstate Monica Nov 09 '13 at 05:03
  • 1
    Okay, here is a math statement against using multiplication: `0` is 3 times more likely to appear than `1` as the first bit. Does that sound about right? (It's 6:30 in the morning over here....) – Jongware Nov 09 '13 at 05:38
  • 1
    @chux - there is no functional difference, 0-32767 falls in the first 15 bits, so unless you have a platform where XOR bitops are faster than OR bitops(they _do_ exist), it really wouldn't be. A `union{int x;struct{ short a:15; short b:15; short pad:2; }random; }u` would eliminate both, but needs c99 to be dependable. – technosaurus Nov 09 '13 at 19:39
  • @technosaurus `RAND_MAX` is 15 bits per OP's situation. `RAND_MAX` is at _least_ 15 bits per the C spec. Thus using `^` versus `|` deals well with the case where `RAND_MAX` is more than 15 bits. – chux - Reinstate Monica Nov 09 '13 at 20:40
  • 1
    @chux good point, it keeps from having to mask with & 0x7FFF for systems where rand() may return more than 15bits. I think I'll compare the asm to the bitfield union to see what the compiler does. – technosaurus Nov 09 '13 at 22:04
0

Use this function, it will give you random number between two number (min and max) :

unsigned long int my_rand (unsigned long int Min, unsigned long int Max)
{
  static int first = 0;
  if (first == 0)
  {
    srand (time (NULL)); //initialize generator of random number
    first = 1;
  }
  return ((unsigned long int)(rand() * (Max+1 - Min) / RAND_MAX + Min));
}