generate random number between 10 to 1000000000 in C [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am using this code to create; but all the results are in range of 10 to 32000.
Can you tell me what I am doing wrong?
for (i = 0; i < N; i++) {
*(A + i) = rand() % (1000000000 - 10 + 1) + 10;
printf("%lu\n", *(A + i));
}

rand() returns a value in the range of 0 and RAND_MAX (which, according to the standard, is at least 32767): https://www.tutorialspoint.com/c_standard_library/c_function_rand.htm
If you want a higher value you can multiply multiple rand() results.

1,000,000,000 (3B9ACA00) is a 30-bit number.
rand() generates results in the [0...RAND_MAX] range. RAND_MAX may be as small as 32,767, a 15-bit number// RAND_MAX may be as large as INT_MAX. Multiple calls to rand() are needed when RAND_MAX < (1000000000 - 10 + 1), the number of different values sought by OP.
The below throws out small or larges values (about 7% of the time) and tries again. This is done to maintain a fair distribution of numbers.
uint32_t rand_10_to_1000000000(void) {
// This method only works well when RAND_MAX is 2**n -1.
// This is commonly true
assert((RAND_MAX + (uint32_t) 1) & RAND_MAX == 0);
uint32_t r;
do {
r = rand();
#if RAND_MAX < 0x3FFFFFFF
// Adding 1 to RAND_MAX as an int should be avoided to prevent int overflow.
r *= RAND_MAX + (uint32_t) 1;
r += rand();
#endif
r &= 0x3FFFFFFF; // only use lower 30 bits.
} while (r < 10 || r > 1000000000);
return r;
}

Here is what documentation says about rand() return value:
An integer value between 0 and RAND_MAX.
And here is what documentation says about RAND_MAX:
This value is library-dependent, but is guaranteed to be at least 32767 on any standard library implementation.
So in your implementation RAND_MAX can probably generate numbers up to 32767. You probably have to generate upper and lower bits independently like:
int big_rand()
{
return rand() | (rand() << 15);
}

Your system's implementation of rand() has limited precision. The standard mandates that RAND_MAX be at least 32767. You system seems to use this minimum value.
You can combine multiple random values to compute your samples:
for (i = 0; i < N; i++) {
A[i] = 10 + (rand() | ((unsigned)rand() << 15)) % (1000000000 - 10 + 1);
printf("%lu\n", A[i]);
}
PS: why do you write *(A+i) instead of the more readable A[i]?

Related

Adding two large numbers together [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have two large numbers stored in an array(p->numbers[50] and q->numbers[50]), and printed out in hexadecimal
1319df046
111111111
When added together, I am returned with, in hexadecimal,
242af'11'257
However, apparently my answer "should" be
242af0157
There is a discrepancy when adding the f and 1 together, equaling 17, but printing 11 (as 17 is 11 in hexadecimal). I'm not sure why my output should be a 0 instead of 11
int sum = 0;
int carry = 0;
for(i = 9; i >= 0; i--)
{
sum = p->numbers[i] + q->numbers[i];
sum = sum + carry;
answer[i] = sum;
carry = sum / 10;
printf("%x", answer[i]);
}
I reproduced your results by defining the arrays of digits as follows:
int p[] = {0x6,0x4,0x0,0xf,0xd,0x9,0x1,0x3,0x1,0x0};
int q[] = {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0};
This is not storing the number as decimal, but as hexadecimal digits.
With that in mind, there are three problems here:
First, the way you're calculating the carry is incorrect. Because the digits are hexadecimal and not decimal, the carry should be sum / 16 instead of sum / 10.
Second, when there is a carry involved, you're not removing the high digit of the sum. In one place, you have 0xf + 0x1 + 0x1 = 0x11 and both characters are being printed. You need to set the digit as answer[i] = sum % 16;
Third, you're adding the digits from largest to smallest. You need to add them from smallest to largest in one loop, then print the digits from largest to smallest in a separate loop.
With those fixes in place, your code should look like this:
for(i = 0; i < 10; i++)
{
sum = p[i] + q[i];
sum = sum + carry;
answer[i] = sum % 16;
carry = sum / 16;
}
for(i=9; i>=0; i--) {
printf("%x", answer[i]);
}

Efficient random function when I want only 0 or 1

I know you can use rand() % 2 to get a random choice of 0 and 1 in C, but is there something more efficient?
My question is not so much about C specifically but about how random number generators work. If I understand correctly, they do some complicated math on the seed to get an even distribution between 0 and RAND_MAX, but is there a way to do less math if you just need a binary choice?
Thanks
is there a way to do less math if you just need a binary choice?
Yes, but it depends on how "good" a random distribution and sequence (or apparent lack) is required. C does not specify the quality of rand(). With quality of randomness specified, alternative solutions exist. How fast? - it depends on many things not supplied by OP. If code is to use rand(), the below will modestly improve performance over a simple rand() % 2u
Call rand() once in a while to extract n random bits and use 1 of those bits per call.
This function uses RAND_MAX to rate the number of bits n received per rand() call. A value of RAND_MAX == 32767 or 0x7FFF would imply 15 random bits.
int rand01(void) {
// Insure RAND_MAX is a power-of-2 - 1
assert(((RAND_MAX + 1u) & RAND_MAX) == 0);
static unsigned rmax = 0;
static int rbits;
if (rmax == 0) {
rmax = RAND_MAX;
rbits = rand();
}
rmax /= 2u;
int r = rbits%2u;
rbits /= 2u;
return r;
}
Note that this approach does not reset the random state completely with srand() . A srand() call is not aware of this function's state.
maybe you can try using my method:
int i;
i = time(NULL) % 2;
this only works if you don't do more than one random per second but you can also do:
struct timeval tv;
gettimeofday(&tv,NULL);
unsigned long random_number = (1000000 * tv.tv_sec + tv.tv_usec) % 2;
this will update your random number at a microsec rate.

What does rand() do in C? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
What does rand() do in C? I don't use C++, just C.
Visual Studio 2012 tells me that its return type is int __cdecl
And it is part of stdlib.h
It does not take any parameters.
How can I set the range in which it generates (pseudo)random numbers?
Your answers are greatly appreciated
Now that there's an actual question: You can't. The range is fixed, and it's defined by the constant RAND_MAX if you need to know it (it's [0 .. RAND_MAX])
If you want a different range, you have to arrange that yourself, typically using the modulo operator % and optionally an offset ... for random numbers between 5 and 9 use
int foo = rand() % 5 + 5;
I use a helper function like this in the game i recently wrote:
int
randomNum(int min, int max)
{
static int seeded = 0;
if (!seeded)
{
seeded = 1;
srand((unsigned int)time(0));
}
return (rand() % (max-min+1)) + min;
}
Depends on the compiler. This wiki article contains a list of them: linear congruential generator
If you need to extend the range of rand(), call it multiple times and merge the outputs:
unsigned int r;
/* ... */
r = ((rand()>>4) & 0xff)<< 0;
r += ((rand()>>4) & 0xff)<< 8;
r += ((rand()>>4) & 0xff)<<16;
r += ((rand()>>4) & 0xff)<<24;
Example program to show how rand works by comparing the returned value. This works with Microsoft compiles (no mismatch).
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char* argv[])
{
unsigned int seed = 1;
unsigned int rand1, rand2;
unsigned int i;
for(i = 0; i < 20; i++){
seed = seed*214013 + 2531011;
rand1 = (seed >> 16) & 0x7fffu;
rand2 = rand();
if(rand1 != rand2)
printf("mismatch %d %d\n", rand1, rand2);
}
return(0);
}
Since only 15 bits of the seed are returned by this version of rand(), then RAND_MAX would be 32767 or hex 0x7fff. As noted in the wiki article, the period is 2^32, this means that seed will cycle through all 4,294,967,296 possible 32 bit values, never repeating until the 4,294,967,296 call to rand(), where seed will have cycled back to 1.

How to get a larger random number from the c function rand()

I am in a coding environment where I only have access to some most basic c functions. #include'ing other lib is not feasible.
In this environment, I can call rand() which gives me a random number between 0 to 32767 inclusively(I think) in my environment. Is the following code the right logic to get a larger random number that is evenly distributed like/as rand()?
rnum = rand() * (32767 + 1) + rand();
rnum = (rand() << 15) | rand() might be faster, but if you need good quality random numbers you should look for an external library. Built-in random functions are generally adequate only for the simplest applications.
static unsigned long next = 1;
int my_rand(void) {
next = next * 1103515245 + 12345;
return((unsigned)(next/65536) % (RAND_MAX+1));
}
void my_srand(unsigned int seed) {
next = seed;
}
on linux
#define RAND_MAX 2147483647
your environment RAND_MAX is probably 32767
reference: http://en.wikipedia.org/wiki/Linear_congruential_generator
if you are not memory constrained you can look also at http://en.wikipedia.org/wiki/Mersenne_twister the code is embeddable as like as the example above
Before using ANY random number generator for a non-trivial use, it should be tested extensively. Here is a link to one article on this subject.
A fun background on the weaknesses of even true random numbers is available in the various histories on the code-breakers at Bletchley Park in WWII. The Germans and Hitler for most of the war assumed their codes were unbreakable because of being encrypted with random numbers, whereas the British were breaking all of these codes completely within months because of various weaknesses in the German implementation of "randomness". Many codes were sufficiently "twisted", if not outright broken, within a few days or months, sufficiently to be of use even though not completely broken.
Besides the other excellent solutions proposed here, you can also do a power expansion in RAND_MAX, truncate at a user defined MY_RAND_MAX, and discard solutions which would cause uniformity to be destroyed.
int myrand(int MY_RAND_MAX)
{
int j = 0, num = 0;
// Generate digits for expansion in powers of RAND_MAX, up to acceptable range.
while (pow(RAND_MAX + 1, j) <= MY_RAND_MAX){
num = num + rand() * (int)pow(RAND_MAX + 1, j);
j++;
}
//compute remainder to determine truncation
int remainder = ((int)pow(RAND_MAX + 1, j)) % (MY_RAND_MAX + 1);
// If number is within accepted bounds, mod and return
if (num <= ( (int)pow(RAND_MAX + 1, j) - remainder ) ){
return (num % (MY_RAND_MAX + 1));
// Else, if number generated exceeds allowed bounds, rerun method.
}else if (num > ( (int)pow(RAND_MAX + 1, j) - remainder ) ){
return myrand(MY_RAND_MAX);
}else{
exit(-1);
}
}
You can check empirically that this method gives you a statistically uniform output in the given range.
I've done so for several trials with different ranges, each with a sample size of 100000, and got an agreement between the variance of the sample and the expected variance to at least 3 sig. fig.s each time.
p.s. I am not a coder, but a mathematician/physicist who has recently learnt to code, so any and all feedback on the quality of my code would be appreciated.

How do I get a specific range of numbers from rand()?

srand(time(null));
printf("%d", rand());
Gives a high-range random number (0-32000ish), but I only need about 0-63 or 0-127, though I'm not sure how to go about it. Any help?
rand() % (max_number + 1 - minimum_number) + minimum_number
So, for 0-65:
rand() % (65 + 1 - 0) + 0
(obviously you can leave the 0 off, but it's there for completeness).
Note that this will bias the randomness slightly, but probably not anything to be concerned about if you're not doing something particularly sensitive.
You can use this:
int random(int min, int max){
return min + rand() / (RAND_MAX / (max - min + 1) + 1);
}
From the:
comp.lang.c FAQ list · Question 13.16
Q: How can I get random integers in a certain range?
A: The obvious way,
rand() % N /* POOR */
(which tries to return numbers from 0 to N-1) is poor, because the
low-order bits of many random number generators are distressingly
non-random. (See question 13.18.) A better method is something like
(int)((double)rand() / ((double)RAND_MAX + 1) * N)
If you'd rather not use floating point, another method is
rand() / (RAND_MAX / N + 1)
If you just need to do something with probability 1/N, you could use
if(rand() < (RAND_MAX+1u) / N)
All these methods obviously require knowing RAND_MAX (which ANSI #defines in <stdlib.h>), and assume that N is much less than RAND_MAX. When N is close to RAND_MAX, and if the range of the random number
generator is not a multiple of N (i.e. if (RAND_MAX+1) % N != 0), all
of these methods break down: some outputs occur more often than
others. (Using floating point does not help; the problem is that rand
returns RAND_MAX+1 distinct values, which cannot always be evenly
divvied up into N buckets.) If this is a problem, about the only thing
you can do is to call rand multiple times, discarding certain values:
unsigned int x = (RAND_MAX + 1u) / N;
unsigned int y = x * N;
unsigned int r;
do {
r = rand();
} while(r >= y);
return r / x;
For any of these techniques, it's straightforward to shift the range,
if necessary; numbers in the range [M, N] could be generated with
something like
M + rand() / (RAND_MAX / (N - M + 1) + 1)
(Note, by the way, that RAND_MAX is a constant telling you what the
fixed range of the C library rand function is. You cannot set RAND_MAX
to some other value, and there is no way of requesting that rand
return numbers in some other range.)
If you're starting with a random number generator which returns
floating-point values between 0 and 1 (such as the last version of
PMrand alluded to in question 13.15, or drand48 in question
13.21), all you have to do to get integers from 0 to N-1 is
multiply the output of that generator by N:
(int)(drand48() * N)
Additional links
References: K&R2 Sec. 7.8.7 p. 168
PCS Sec. 11 p. 172
Quote from: http://c-faq.com/lib/randrange.html
check here
http://c-faq.com/lib/randrange.html
For any of these techniques, it's straightforward to shift the range, if necessary; numbers in the range [M, N] could be generated with something like
M + rand() / (RAND_MAX / (N - M + 1) + 1)
Taking the modulo of the result, as the other posters have asserted will give you something that's nearly random, but not perfectly so.
Consider this extreme example, suppose you wanted to simulate a coin toss, returning either 0 or 1. You might do this:
isHeads = ( rand() % 2 ) == 1;
Looks harmless enough, right? Suppose that RAND_MAX is only 3. It's much higher of course, but the point here is that there's a bias when you use a modulus that doesn't evenly divide RAND_MAX. If you want high quality random numbers, you're going to have a problem.
Consider my example. The possible outcomes are:
rand()
freq.
rand() % 2
0
1/3
0
1
1/3
1
2
1/3
0
Hence, "tails" will happen twice as often as "heads"!
Mr. Atwood discusses this matter in this Coding Horror Article
The naive way to do it is:
int myRand = rand() % 66; // for 0-65
This will likely be a very slightly non-uniform distribution (depending on your maximum value), but it's pretty close.
To explain why it's not quite uniform, consider this very simplified example:
Suppose RAND_MAX is 4 and you want a number from 0-2. The possible values you can get are shown in this table:
rand() | rand() % 3
---------+------------
0 | 0
1 | 1
2 | 2
3 | 0
See the problem? If your maximum value is not an even divisor of RAND_MAX, you'll be more likely to choose small values. However, since RAND_MAX is generally 32767, the bias is likely to be small enough to get away with for most purposes.
There are various ways to get around this problem; see here for an explanation of how Java's Random handles it.
rand() will return numbers between 0 and RAND_MAX, which is at least 32767.
If you want to get a number within a range, you can just use modulo.
int value = rand() % 66; // 0-65
For more accuracy, check out this article. It discusses why modulo is not necessarily good (bad distributions, particularly on the high end), and provides various options.
As others have noted, simply using a modulus will skew the probabilities for individual numbers so that smaller numbers are preferred.
A very ingenious and good solution to that problem is used in Java's java.util.Random class:
public int nextInt(int n) {
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
if ((n & -n) == n) // i.e., n is a power of 2
return (int)((n * (long)next(31)) >> 31);
int bits, val;
do {
bits = next(31);
val = bits % n;
} while (bits - val + (n-1) < 0);
return val;
}
It took me a while to understand why it works and I leave that as an exercise for the reader but it's a pretty concise solution which will ensure that numbers have equal probabilities.
The important part in that piece of code is the condition for the while loop, which rejects numbers that fall in the range of numbers which otherwise would result in an uneven distribution.
double scale = 1.0 / ((double) RAND_MAX + 1.0);
int min, max;
...
rval = (int)(rand() * scale * (max - min + 1) + min);
Updated to not use a #define
double RAND(double min, double max)
{
return (double)rand()/(double)RAND_MAX * (max - min) + min;
}
If you don't overly care about the 'randomness' of the low-order bits, just rand() % HI_VAL.
Also:
(double)rand() / (double)RAND_MAX; // lazy way to get [0.0, 1.0)
This answer does not focus on the randomness but on the arithmetic order.
To get a number within a range, usually we can do it like this:
// the range is between [aMin, aMax]
double f = (double)rand() / RAND_MAX;
double result = aMin + f * (aMax - aMin);
However, there is a possibility that (aMax - aMin) overflows. E.g. aMax = 1, aMin = -DBL_MAX. A safer way is to write like this:
// the range is between [aMin, aMax]
double f = (double)rand() / RAND_MAX;
double result = aMin - f * aMin + f * aMax;
Based on this concept, something like this may cause a problem.
rand() % (max_number + 1 - minimum_number) + minimum_number
// 1. max_number + 1 might overflow
// 2. max_number + 1 - min_number might overflow
if you care about the quality of your random numbers don't use rand()
use some other prng like http://en.wikipedia.org/wiki/Mersenne_twister or one of the other high quality prng's out there
then just go with the modulus.
Just to add some extra detail to the existing answers.
The mod % operation will always perform a complete division and therefore yield a remainder less than the divisor.
x % y = x - (y * floor((x/y)))
An example of a random range finding function with comments:
uint32_t rand_range(uint32_t n, uint32_t m) {
// size of range, inclusive
const uint32_t length_of_range = m - n + 1;
// add n so that we don't return a number below our range
return (uint32_t)(rand() % length_of_range + n);
}
Another interesting property as per the above:
x % y = x, if x < y
const uint32_t value = rand_range(1, RAND_MAX); // results in rand() % RAND_MAX + 1
// TRUE for all x = RAND_MAX, where x is the result of rand()
assert(value == RAND_MAX);
result of rand()
2 cents (ok 4 cents):
n = rand()
x = result
l = limit
n/RAND_MAX = x/l
Refactor:
(l/1)*(n/RAND_MAX) = (x/l)*(l/1)
Gives:
x = l*n/RAND_MAX
int randn(int limit)
{
return limit*rand()/RAND_MAX;
}
int i;
for (i = 0; i < 100; i++) {
printf("%d ", randn(10));
if (!(i % 16)) printf("\n");
}
> test
0
5 1 8 5 4 3 8 8 7 1 8 7 5 3 0 0
3 1 1 9 4 1 0 0 3 5 5 6 6 1 6 4
3 0 6 7 8 5 3 8 7 9 9 5 1 4 2 8
2 7 8 9 9 6 3 2 2 8 0 3 0 6 0 0
9 2 2 5 6 8 7 4 2 7 4 4 9 7 1 5
3 7 6 5 3 1 2 4 8 5 9 7 3 1 6 4
0 6 5
Just using rand() will give you same random numbers when running program multiple times. i.e. when you run your program first time it would produce random number x,y and z. If you run the program again then it will produce same x,y and z numbers as observed by me.
The solution I found to keep it unique every time is using srand()
Here is the additional code,
#include<stdlib.h>
#include<time.h>
time_t t;
srand((unsigned) time(&t));
int rand_number = rand() % (65 + 1 - 0) + 0 //i.e Random numbers in range 0-65.
To set range you can use formula : rand() % (max_number + 1 - minimum_number) + minimum_number
Hope it helps!
You can change it by adding a % in front of the rand function in order to change to code
For example:
rand() % 50
will give you a random number in a range of 50. For you, replace 50 with 63 or 127
I think the following does it semi right. It's been awhile since I've touched C. The idea is to use division since modulus doesn't always give random results. I added 1 to RAND_MAX since there are that many possible values coming from rand including 0. And since the range is also 0 inclusive, I added 1 there too. I think the math is arranged correctly avoid integer math problems.
#define MK_DIVISOR(max) ((int)((unsigned int)RAND_MAX+1/(max+1)))
num = rand()/MK_DIVISOR(65);
Simpler alternative to #Joey's answer. If you decide to go with the % method, you need to do a reroll to get the correct distribution. However, you can skip rerolls most of the time because you only need to avoid numbers that fall in the last bucket:
int rand_less_than(int max) {
int last_bucket_min = RAND_MAX - RAND_MAX % max;
int value;
do {
value = rand();
} while (last_bucket_min <= value);
return value % max;
}
See #JarosrawPawlak's article for explanation with diagrams: Random number generator using modulo
In case of RAND_MAX < max, you need to expand the generator: Expand a random range from 1–5 to 1–7
#include <stdio.h>
#include <stdlib.h>
#include <time.h> // this line is necessary
int main() {
srand(time(NULL)); // this line is necessary
int random_number = rand() % 65; // [0-64]
return 0;
}
Foy any range between min_num and max_num:
int random_number = rand() % (max_num + 1 - min_num) + min_num;

Resources