tags:

views:

310

answers:

7

Hi How I can get in C++ random value from 01 to 12?

So I will have 03, or 06, or 11?

+9  A: 
#include <iomanip>
#include <iostream>
#include <stdlib.h>
#include <time.h>

// initialize random seed
srand( time(NULL) );

// generate random number
int randomNumber = rand() % 12 + 1;

// output, as you seem to wan a '0'
cout << setfill ('0') << setw (2) << randomNumber;

to adress dirkgently's issue maybe something like that would be better?

// generate random number
int randomNumber = rand()>>4; // get rid of the first 4 bits

// get the value
randomNumer = randomNumer % 12 + 1;

edit after mre and dirkgently's comments

f4
Exactly : ) + 1
SDReyes
Poor method because the low-order bits of many random number generators are distressingly non-random. Read the FAQ I posted in my answer.
dirkgently
@dirkgently I bet this is just homework, so he doesn't much care if the numbers aren't truly random.
Earlz
+1 You were just too fast ;) Maybe change to std::cout
mre
@Earlz: Homework is about learning things right. Not copy-pasting. Hence, my answer does not have a full solution. A hint only. A very, very important hint to keep in mind.
dirkgently
<Pedantic> Missing #include <iomanip> and it's std::setfill and std::setw </Pedantic>
mre
+7  A: 

Use the following formula:

M + rand() / (RAND_MAX / (N - M + 1) + 1), M = 1, N = 12

and read up on this FAQ.

Edit: Most answers on this question do not take into account the fact that poor PRN generators (typically offered with the library function rand()) are not very random in the low order bits. Hence:

rand() % 12 + 1

is not good enough.

dirkgently
Using division gives only a minute improvement by itself -- the results *may* be more random, but they're still usually skewed. Assuming `rand()` produces all numbers up to RAND_MAX with equal probability, this will NOT produce numbers from 1 to 12 with equal probability, except in the (vanishingly rare) case that RAND_MAX happens to be a multiple of 12.
Jerry Coffin
+1 for raising the statistical bias issue from using the naive % approach.
Clifford
@Jerry: to be fair the FAQ linked gives other solutions.
Clifford
@Clifford: I hadn't checked the link, but you're right. Then again, if memory serves, I was partially responsible for what's in the FAQ...
Jerry Coffin
Actually, re-checking, it looks like I probably wasn't. For anybody who cares what I'm talking about, see: http://groups.google.com/group/comp.lang.c/browse_frm/thread/5a034f20e4981e53/8b4393f2ec2e40e7?hl=en#8b4393f2ec2e40e7
Jerry Coffin
+1  A: 

(rand() % 12 + 1).ToString("D2")

Roo
The question is tagged C++, not C# or whatever that code is.
AndiDog
if someone can't figure out how to convert that to c++ then I question the ability to do any programming.
Tim
@tim:but at that point, it's basically not doing much more than echoing back the question. How do a print with two decimal places? Do the conversion with two decimal places! Oh, and along with that giving the same (bad) advice about how to reduce the range as at least half a dozen others...
Jerry Coffin
Boy, SO is turned into a crutch for people who have no idea how to figure out pretty simple things... I guess I am getting old and crotchety.
Tim
A: 

You can do this, for example:

#include <cstdlib>
#include <cstdio>
#include <time.h>

int main(int argc, char **argv)
{
    srand(time(0));

    printf("Random number between 1 and 12: %d", (rand() % 12) + 1);
}

The srand function will seed the random number generator with the current time (in seconds) - that's the way it's usually done, but there are also more secure solutions.

rand() % 12 will give you a number between 0 and 11 (% is the modulus operator), so we add 1 here to get to your desired range of 1 to 12.

In order to print 01 02 03 and so on instead of 1 2 3, you can format the output:

printf("Random number between 01 and 12: %02d", (rand() % 12) + 1);
AndiDog
A: 

Is there some significance to the leading zero in this case? Do you intend for it to be octal, so the 12 is really 10 (in base 10)?

Getting a random number within a specified range is fairly straightforward:

int rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
 */

    int divisor = RAND_MAX/(limit+1);
    int retval;

    do { 
        retval = rand() / divisor;
    } while (retval > limit);

    return retval;
}

(The while loop is to prevent skewed results -- some outputs happening more often than others). Skewed results are almost inevitable when/if you use division (or its remainder) directly.

If you want to print it out so even one-digit numbers show two digits (i.e. a leading 0), you can do something like:

std::cout << std::setw(2) << std::setprecision(2) << std::setfill('0') << number;
Jerry Coffin
A: 

Probably not terribly speed efficient - but wouldn't the best way to spread evenly across the entire range of RAND_MAX be to simply raise the result to an approriate (fractional) power?

eg. If RAND_MAX is 32768 and you want 0-12 then
RAND_MAX ^ x = 12, so x = ln(12)/ln(32768) = 0.2389

and result = pow(rand(),0.2389)

Martin Beckett
How is this an improvement on using division?
Jerry Coffin
This is no longer a uniform variant. It may be random, but doesn't posses one of the common properties of a random number, i.e., uniform distribution in the range.
miked
@miked - of course, wasn't think it through!
Martin Beckett
A: 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

int get_random(int n) {
    struct timeval num;
    gettimeofday(&num, NULL);
    srand(num.tv_usec);
    return rand() % n + 1;
}

int main () {
    printf("Random number between 1 and 12: %d \n", get_random(12));
    return 0;
}
gmunkhbaatarmn
Don't seed a RNG on every call (with srand), that makes it even less random.
msw