LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 07-26-2004, 02:52 AM   #1
suchi_s
Member
 
Registered: May 2004
Posts: 133

Rep: Reputation: 15
srand in c


how to use srand function to print "randomn numbers of eight digits" veerytime
 
Old 07-26-2004, 03:22 AM   #2
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 53
srand() is used to seed the random number generator, not get random numbers. Are you asking for a list of numbers that each have 8 digits? Something like 98239478?

Here's a program that will do that:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
  int i, j;
  char num[9];

  srand(time(0));

  for(i = 0;i < 5;++i)
  {
    num[0] = '1'+rand()%9;
    for(j = 1;j < 8;++j)
      num[j] = '0'+rand()%10;
    num[8] = '\0';
    printf("%s\n", num);
  }

  return 0;
}
Or if you need them to actually be integers:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>

int main()
{
  int i, j;
  char num[9];
  int64_t realnum;

  srand(time(0));

  for(i = 0;i < 5;++i)
  {
    num[0] = '1'+rand()%9;
    for(j = 1;j < 8;++j)
      num[j] = '0'+rand()%10;
    num[8] = '\0';
    realnum = atoll(num);
    printf("%lld\n", realnum);
  }

  return 0;
}
The first one should work with any C compiler. The second one might be gcc-specific.

time(0) doesn't need to be the seed for the random number generator. You can also use things like getpid() for the seed, but the key is to take the seed from a varying source so you get a different set of random numbers each time.
 
Old 07-26-2004, 04:37 AM   #3
suchi_s
Member
 
Registered: May 2004
Posts: 133

Original Poster
Rep: Reputation: 15
thanku it s working
good very intelligent

can u plz explain what it is all doing..
srand(time(0));

num[0] = '1'+rand()%9;


num[j] = '0'+rand()%10;
num[8] = '\0';
 
Old 07-26-2004, 05:39 AM   #4
Mohsen
Member
 
Registered: Feb 2003
Location: Iran
Distribution: Solaris 10
Posts: 201

Rep: Reputation: 30
Prototype: void srand(unsigned int seed);
Obviously the seed has to change every time the program is run. One way to do this is to feed it the O/P from time

time(0); // get the calender time, Number of seconds since 1st Jan 1970.


after a call to srand, rand() will generate a random number between 0 and 'RAND_MAX', which has a more random value!

without using srand and time(0) as its parameter (shich differs from time to time), each time you run your program, the sequence if random numbers returned by rand() is the same.
 
Old 07-26-2004, 05:42 AM   #5
suchi_s
Member
 
Registered: May 2004
Posts: 133

Original Poster
Rep: Reputation: 15
num[0] = '1'+rand()%9;


num[j] = '0'+rand()%10;
how it works
 
Old 07-26-2004, 05:44 AM   #6
suchi_s
Member
 
Registered: May 2004
Posts: 133

Original Poster
Rep: Reputation: 15
why % of 9
and then 10
 
Old 07-26-2004, 08:47 AM   #7
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 53
Because if the first digit is a 0, if you convert the string to a number and then display it, you'll only get 7 digits (it won't show something like 07423489, it just shows 7423489). So to ensure that you get an 8 digit number it makes the first digit be 1 through 9 instead of 0 through 9 like the rest of them.

The rand() function returns a number from 0 up to RAND_MAX. The % operator divides by the number on the left by the number on the right and then returns the remainder. So basically this makes rand() return a number between 0 and the number on the right side of the % instead.

Last edited by itsme86; 07-26-2004 at 08:50 AM.
 
Old 07-26-2004, 01:11 PM   #8
psiakr3w
LQ Newbie
 
Registered: Jul 2004
Posts: 27

Rep: Reputation: 15
I was wondering how exactly the following statement works:

num[0] = '1'+rand()%9;

I was puzzled how adding a number (rand()%9) to a character ('1') works, but I eventually figured it out, remembering an example from "The C Programming Language." Here's my explanation, in case someone has the same question:

A character is actually just a small integer. For instance, according to http://www.asciitable.com/, a '1' is just 49. And it so happens that the ascii code defines the digits '0' through '9' consecutively ('0' is 48, '1' is 49, '2' is 50, etc.), so an expression like '1' + 2 (2 is one possible value of 'rand()%9', for example), would give 51, which corresponds to a '3' being stored in num[0] -- the first element of the character array.
 
Old 07-26-2004, 01:21 PM   #9
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 53
Exactly.
 
Old 07-27-2004, 05:36 AM   #10
suchi_s
Member
 
Registered: May 2004
Posts: 133

Original Poster
Rep: Reputation: 15
when i run this prog for 40000 numbers some of the numbers are same..
(means repetitive occurance) why?
how to overcome
 
Old 07-27-2004, 07:27 AM   #11
suchi_s
Member
 
Registered: May 2004
Posts: 133

Original Poster
Rep: Reputation: 15
if im run the progranm again after 2 mins for next 40000 numbers some of the numbers are same which were generated previously
 
Old 07-27-2004, 07:28 AM   #12
suchi_s
Member
 
Registered: May 2004
Posts: 133

Original Poster
Rep: Reputation: 15
how do i overcome
every time i run the program numbers should be unique
 
Old 07-27-2004, 09:34 AM   #13
barisdemiray
Member
 
Registered: Sep 2003
Location: Ankara/Turkey
Distribution: Slackware
Posts: 155

Rep: Reputation: 30
There are two solutions i can remember to random but unique numbers problem. First one is using an extra array of numbers and copying all the numbers you generate to this array and checking all newly generated numbers with this array; if exist create a new one again steps. But this consumes too much memory --especially with 8 digits numbers which requires bigger type than int- and CPU time --assume that you have to create too much unique number- The main idea here is creating a sequential array of 8-digits numbers (like 10000000,10000001,10000002,.. or 10000001,10000004,10000009) and swapping the numbers randomly (select two numbers randomly and swap them). Then you will get a 8-digit random number array.. Hope this helps.
 
Old 07-27-2004, 12:06 PM   #14
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,524

Rep: Reputation: 93
Quote:
Originally posted by suchi_s
when i run this prog for 40000 numbers some of the numbers are same..
(means repetitive occurance) why?
how to overcome
Quote:
Originally posted by suchi_s
if im run the progranm again after 2 mins for next 40000 numbers some of the numbers are same which were generated previously
Well, of course this can happen. Random is random, and if you generate 40000 out of 90000000 possible numbers, there's a reasonable chance there will be duplicates.

However, then rand() function from glibc is not bad, but it may be not strong enough for your tests.

Here's a program that uses the random generator from the Linux-kernel (if it is configured in your kernel. Probably it is.). I suppose this is a better random generator than the one from glibc.

It also generates 8-digit numbers, but it includes numbers starting with one or more zeroes (e.g. 00234978 is possible). (If you don't want this, it can be easily fixed the same way as the example's given earlier in the thread).
Code:
#include <stdio.h>

int main()
{
	 unsigned int rnd;
	 FILE *fp;

	 if ((fp = fopen("/dev/urandom", "r")) == NULL) {
		  perror("");
		  return 1;
	 }
	 if (fread(&rnd, 1, sizeof(rnd), fp) != sizeof(rnd)) {
		  fprintf(stderr, "Error reading random number from device file\n");
		  return 1;
	 }
	 rnd %= 100000000;  /* A '1' with 8 zeroes (for 8 digits) */
	 printf("%.8u\n", rnd); /* print at least 8 digits, padding with 0's if needed */
	 return 0;
}
I ran a few tests, but it also has duplicates in the results. This is normal, throw a dice 40000 times, and I'm sure you will have duplicates

To test for duplicates, I used the command below. It prints only numbers that ocurred more than once. (the compiled random program is called "randdigits" here)
Code:
for i in `seq 1 40000` ; do ./randdigits ; done | sort | uniq -d
If you really don't want duplicates in the result, stick with barisdemiray's suggestion, and maybe combine it with my program for (arguably ?) better randomization.

Last edited by Hko; 07-27-2004 at 12:14 PM.
 
Old 07-27-2004, 01:14 PM   #15
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 53
From what I understand, /dev/urandom is truely random as opposed to the rand() function which is only pseudo random. rand() generates "random" numbers by numeric computation. /dev/urandom is built from harddrive accesses and other events that, in combination with each other, produce true randomness. The key is that /dev/urandom is built using random input like user key presses and such.

But just because it's truely random doesn't mean you'll never get duplicate results. Here's a program that will give you 40,000 unique 8-digit random numbers.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
  int i, j;
  unsigned char num[9];
  int64_t numlist[40000];
  int fd;

  if((fd = open("/dev/urandom", O_RDONLY)) == -1)
  {
    puts("Couldn't open /dev/urandom for reading.");
    exit(1);
  }

  num[8] = '\0';
  for(i = 0;i < 40000;++i)
  {
    do
    {
      read(fd, num, 8);
      num[0] = '1'+(num[0]%9);
      for(j = 1;j < 8;++j)
        num[j] = '0'+(num[j]%10);
      numlist[i] = atoll(num);

      for(j = 0;j < i;++j)
        if(numlist[i] == numlist[j])
          break;
    } while(j < i);
  }

  close(fd);

  return 0;
}
When the outer loop finishes, numlist will contain your list of unique 8-digit numbers. If you add a loop that prints the list of numbers and run it like I did below, you'll see that it works.

Quote:
itsme@itsme:~/C$ ./randtest | sort | uniq | wc -l
40000

Last edited by itsme86; 07-27-2004 at 01:57 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
srand(), rand(), RAND_MAX, or XXX weirdness nazdrowie Programming 2 03-07-2005 12:45 PM


All times are GMT -5. The time now is 05:27 AM.

Main Menu
 
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration