LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
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
 
Search this Thread
Old 08-15-2003, 12:53 AM   #1
KneeLess
Member
 
Registered: May 2003
Distribution: Debian GNU/Linux 3.0 Sid, OpenBSD 3.5
Posts: 190

Rep: Reputation: 30
Need help using rand() in C


Disregard last "EDIT".

Okay, sorry gents (and any ladies) for this question. But I just couldn't stomp out the problem. And I have zero friends that program in C, so no help there. Well I was trying to make a dice rolling program. It takes the number of sides feeds it to genNum() (take a look at the code) and then uses rand() to generate a number, and then feeds it down an if(). Probably a slow and painful way to go about this, but it's the only way I could think of. This code compiles, but it never achieves a number above 41, or below 3.

Code:
#include <stdio.h>
#include <stdlib.h>

void genNum( int );

main()
{
	int dieSide = 0;
	printf("\nHow many sides does the die have? ");
	scanf("%d", &dieSide);
	genNum( dieSide );
	return 0;
}

void genNum( int SidesOfDie )
{
	int dieNum = 0;
	dieNum = rand();
	if( (dieNum <= SidesOfDie) && (dieNum != 0) )
	{
		printf("The number is %d\n\n", dieNum);
	}
	else
	{
		genNum( SidesOfDie );
	}
}
Any help debugging this would be much apprechiated (wow, spelling errors suck). And no, don't answer this question if you feel I needed google (which I checked).

Thanks.

Last edited by KneeLess; 08-15-2003 at 12:58 AM.
 
Old 08-15-2003, 01:16 AM   #2
KneeLess
Member
 
Registered: May 2003
Distribution: Debian GNU/Linux 3.0 Sid, OpenBSD 3.5
Posts: 190

Original Poster
Rep: Reputation: 30
Slightly updated version. Adds error handler for dice with one or less sides.

Code:
#include <stdio.h>
#include <stdlib.h>

void genNum( int );

main()
{
	int dieSide = 0;
	printf("\nHow many sides does the die have? ");
	scanf("%d", &dieSide);
	printf("Sending to genNum()...\n");
	genNum( dieSide );
	return 0;
}

void genNum( int SidesOfDie )
{
	int dieNum = 0;
	dieNum = rand();
	if( (dieNum <= SidesOfDie) && (dieNum != 0) )
	{
		printf("The number is %d\n\n", dieNum);
	}
	else if ( SidesOfDie <= 1 )
	{
		printf("Idiot boy! A dice cannot have one or less sides.\n\n");
	}
	else
	{
		genNum( SidesOfDie );
	}
}
Thanks again.
 
Old 08-15-2003, 04:31 AM   #3
Gethyn
Member
 
Registered: Aug 2003
Location: UK
Distribution: (X)Ubuntu 10.04/10.10, Debian 5, CentOS 5
Posts: 900

Rep: Reputation: 32
I don't know much about C, more about C++, but i believe rand() returns a number between 0 and an internal number called RAND_MAX. The sequence of numbers is what's called "pseudorandom": for a given start number it always gives out the same sequence. I suggest that in main, before you call genNum(), you insert the following line:

srand(time(NULL));

This takes a "seed" for the random number generator from the CPU clock, so at least you won't always get the same sequence. You might also want to consider changing the way genNum() works: it might be better to write

int dieNum = rand() % ((RAND_MAX / sidesOfDie) - (RAND_MAX % sidesOfDie))

The operator % gives you the remainder after dividing one integer by another. You'll need to think about the maths a bit and check it's right (i didn't think too hard to see if it's right i'm afraid!) but it might help....
 
Old 08-15-2003, 04:54 AM   #4
kev82
Senior Member
 
Registered: Apr 2003
Location: Lancaster, England
Distribution: Debian Etch, OS X 10.4
Posts: 1,263

Rep: Reputation: 50
Quote:
by Gethyn
int dieNum = rand() % ((RAND_MAX / sidesOfDie) - (RAND_MAX % sidesOfDie))
im not sure whether that works or not but it might be better to think about it like this, you want to generate a number between 1 and sidesOfDie, so (rand() % sidesOfDie) returns the remainder of dividing rand() by sidesOfDie which will obviously be between 0 and sidesOfDie - 1, add 1 to it and youve got your answer.

1 + (rand() % sidesOfDie)

btw your recursive method could bring you a few nasty emails from the sysadmin.
 
Old 08-15-2003, 05:32 AM   #5
Gethyn
Member
 
Registered: Aug 2003
Location: UK
Distribution: (X)Ubuntu 10.04/10.10, Debian 5, CentOS 5
Posts: 900

Rep: Reputation: 32
I might be thinking about this wrong, but if you just put rand() % sidesOfDie, and sidesOfDie doesn't go exactly into RAND_MAX, then you'll be skewing the probabilities. Let's see if i can explain that:
say RAND_MAX is 10 (obviously far too small but...)
and sidesOfDie is 3
so, if rand() returns 0 you get 0, 1 you get 1, etc
for rand() output 4 you get 1, 5 you get 2, and so on.
The problem arises when rand() returns 10. In this case you'll get 1. However, there are no matching outputs for 2 or 3 (which are valid results from the die)
So in total, the probabilities are :
0 = 4/10 (corresponding to 0, 3, 6, 9)
1 = 4/10 (from 1, 4, 7, 10)
2 = 3/10 (from 2, 5, 8)

This obviously isn't right. If RAND_MAX is big enough compared to sidesOfDie then the effect is negligible, but it's not entirely correct...

When you say my recursive method is going to get me into trouble, please excuse my ignorance, but could you explain? (i take it you're not referring to my somewhat less than excellent programming? )
 
Old 08-15-2003, 05:50 AM   #6
kev82
Senior Member
 
Registered: Apr 2003
Location: Lancaster, England
Distribution: Debian Etch, OS X 10.4
Posts: 1,263

Rep: Reputation: 50
the recusive comment was to kneeless(sorry that wasnt clear, i have aspergers syndrome and tend to think people know everything i know), in regard to him calling getnum recursivly, with a terminating condition that relied on a random number.

as far as the probability skewing goes you are totally correct but as you say sidesOfDie is gonna be much smaller than RAND_MAX so the probabilities are gonna vary by amounts in the magnitude of 4.7*10^-10 (1/randmax) which is really insignificant compared to the 'psuedoness' of the random number generator. if you wanna do some real accurate probability you should use a mathematical library like NAG for fortran, and not use the normal random number generator.

oh and your probabilities are 4/10(0,3,6,9), 3/10(1,4,7), 3/10(2,5,8)
 
Old 08-15-2003, 11:11 AM   #7
KneeLess
Member
 
Registered: May 2003
Distribution: Debian GNU/Linux 3.0 Sid, OpenBSD 3.5
Posts: 190

Original Poster
Rep: Reputation: 30
Thanks a lot guys.

I ended up using Gethyn's method. All I needed was time.h for the srand(time(NULL)), and it works great now.

Kev82, could you point out where my recursive method is?
 
Old 08-15-2003, 11:26 AM   #8
kev82
Senior Member
 
Registered: Apr 2003
Location: Lancaster, England
Distribution: Debian Etch, OS X 10.4
Posts: 1,263

Rep: Reputation: 50
lets pretend that sizeOfDie is 6 and that rand() always returns a number bigger than 6. so we call getNum, dieNum>6(previous sentance) and 6>1 so we call getNum again, and the same thing happens, so we call it again, and again and again and again, until we run out of stack space and generate some sort of signal. hopefully we havnt killed the system while were doing it.

a recursive function is one which calls itsself, all recursive functions have terminating conditions, yours was when dieNum was within the correct bounds but the problem is this condition occurs randomly so may never occur at all.

Last edited by kev82; 08-15-2003 at 11:27 AM.
 
Old 08-15-2003, 11:32 AM   #9
KneeLess
Member
 
Registered: May 2003
Distribution: Debian GNU/Linux 3.0 Sid, OpenBSD 3.5
Posts: 190

Original Poster
Rep: Reputation: 30
Yeah, I probably did the most backasswards way to do it, but as I said: That's all I could think of.
 
Old 08-15-2003, 11:40 AM   #10
kev82
Senior Member
 
Registered: Apr 2003
Location: Lancaster, England
Distribution: Debian Etch, OS X 10.4
Posts: 1,263

Rep: Reputation: 50
now you know the % operator just generate the number like i said above

1 + (rand() % sidesOfDie)
 
Old 10-01-2003, 10:01 AM   #11
Sm0k3
Member
 
Registered: Sep 2003
Location: Chicago
Distribution: Slackware 13 x86_64
Posts: 58

Rep: Reputation: 15
Lightbulb rand()

hey guys (and gals if any), i was reading through this thread hoping i might find an answer to a problem i was having with rand()..

i'm trying to get a random 5 digit integer (i'm going to use it in a crack authentication mechanism, this is a CGI written in C ) the integer will be a 'session id'... i've tried to beat this horse but cant quite get it to work.. every thing i've tried always returns the same thing.

if someone could tell me how to make it 32 digits long, that would be even better but i don't NEED that much.
Quote:
#include <stdio.h>
#include <stdlib.h>

/* omitted.. this is lenghthy... */

long idnum;
idnum = rand()%50000+10024;

/* omitted again.. */
i had also tryied using a char string, and atol(), but that worked with less than favorable results so i am not gonna bother posting it. i admit i'm a HORRIBLE coder
 
Old 10-01-2003, 10:34 AM   #12
kev82
Senior Member
 
Registered: Apr 2003
Location: Lancaster, England
Distribution: Debian Etch, OS X 10.4
Posts: 1,263

Rep: Reputation: 50
i havnt got a compiler in front of me at the moment but how about something like this
Code:
#define NUMDIGITS 5

long number()
{
    char x[NUMDIGITS+1];
    int i;

    for(i=0;i<NUMDIGITS+1;i++) {
        x[i]='0' + rand() %10;
    }

    x[++i] = 0;

    return atol(x);
}
as i say i dont have a compiler and so cant test it but the general idea is there i think.
 
Old 10-01-2003, 12:51 PM   #13
Sm0k3
Member
 
Registered: Sep 2003
Location: Chicago
Distribution: Slackware 13 x86_64
Posts: 58

Rep: Reputation: 15
thanks man, this worked perfectly
 
  


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


Similar Threads
Thread Thread Starter Forum Replies Last Post
rand() and syntax error lmvent Programming 2 10-06-2005 12:21 PM
genrating -2, -1, 1, 2 woth rand() hubabuba Programming 9 08-14-2005 01:59 PM
srand(), rand(), RAND_MAX, or XXX weirdness nazdrowie Programming 2 03-07-2005 12:45 PM
rand() question deiussum Programming 6 11-11-2004 02:10 PM
Simple sh script: rand reorder Sinope Programming 2 09-11-2004 05:24 PM


All times are GMT -5. The time now is 05:02 PM.

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 Google+: linuxquestions
Open Source Consulting | Domain Registration