Getting big random numbers in C/C++
Here's a portable C99 solution that returns a random 64-bit number:
unsigned long long llrand() {
unsigned long long r = 0;
for (int i = 0; i < 5; ++i) {
r = (r << 15) | (rand() & 0x7FFF);
}
return r & 0xFFFFFFFFFFFFFFFFULL;
}
Explanation: rand()
returns integers in the range 0 to RAND_MAX
and RAND_MAX
is only guaranteed to be at least 32,767 (15 random bits). long long
is guaranteed to have 64 bits but may be larger.
How to generate very Large random number in c++
With c++11, using the standard random library of c++11, you can do this:
#include <iostream>
#include <random>
int main()
{
/* Seed */
std::random_device rd;
/* Random number generator */
std::default_random_engine generator(rd());
/* Distribution on which to apply the generator */
std::uniform_int_distribution<long long unsigned> distribution(0,0xFFFFFFFFFFFFFFFF);
for (int i = 0; i < 10; i++) {
std::cout << distribution(generator) << std::endl;
}
return 0;
}
Live Demo
How to generate large random numbers C
random() returns a long which on a 64bit system should be 64 bits. If you are on a 32bit system you could do the following:
#include <inttypes.h>
uint64_t num;
/* add code to seed random number generator */
num = rand();
num = (num << 32) | rand();
// enforce limits of value between 100000000 and 999999999
num = (num % (999999999 - 100000000)) + 100000000;
Alternatively on a NIX system you could read /dev/random into your buffer:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <inttypes.h>
int fd;
uint64_t num;
if ((fd = open("/dev/random", O_RDONLY) == -1)
{
/* handle error */
};
read(fd, &num, 8);
close(fd);
// enforce limits of value between 100000000 and 999999999
num = (num % (999999999 - 100000000)) + 100000000;
A
How to generate a random int in C?
Note: Don't use
rand()
for security. If you need a cryptographically secure number, see this answer instead.
#include <time.h>
#include <stdlib.h>
srand(time(NULL)); // Initialization, should only be called once.
int r = rand(); // Returns a pseudo-random integer between 0 and RAND_MAX.
On Linux, you might prefer to use random and srandom.
Generate big numbers with srand() in c
First of all, check RAND_MAX
for the maximum value that can be generated by rand()
.
You could compose two rand()
results into one value.
int random = (rand() << 16) | rand();
C++ Random number from 1 to a very large number (e.g. 25 million)
You could (should) use the new C++11 std::uniform_real_distribution
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> distribution(1, 25000000);
//generating a random integer:
double random = distribution(gen);
C++ Get random number from 0 to max long long integer
What is rand()
?
According to this the rand()
function returns a value in the range [0,RAND_MAX]
.
What is RAND_MAX
?
According to this, RAND_MAX
is "an integral constant expression whose value is the maximum value returned by the rand function. This value is library-dependent, but is guaranteed to be at least 32767 on any standard library implementation."
Precision Is An Issue
You take rand()/(double)RAND_MAX
, but you have perhaps only 32767 discrete values to work with. Thus, although you have big numbers, you don't really have more numbers. That could be an issue.
Seeding May Be An Issue
Also, you don't talk about how you are calling the function. Do you run the program once with LLONG_MAX
and another time with ULLONG_MAX
? In that case, the behaviour you are seeing is because you are implicitly using the same random seed each time. Put another way, each time you run the program it will generate the exact same sequence of random numbers.
How can I seed?
You can use the srand()
function like so:
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
int main (){
srand (time(NULL));
//The rest of your program goes here
}
Now you will get a new sequence of random numbers each time you run your program.
Overflow Is An Issue
Consider this part ((end - begin)*rand()/(double)RAND_MAX)
.
What is (end-begin)
? It is LLONG_MAX
or ULLONG_MAX
these are, by definition, the largest possible values those data types can hold. Therefore, it would be bad to multiply them by anything. Yet you do! You multiply them by rand()
, which is non-zero. This will cause an overflow. But we can fix that...
Order of Operations Is An Issue
You then divide them by RAND_MAX
. I think you've got your order of operations wrong here. You really meant to say:
((end - begin) * (rand()/(double)RAND_MAX) )
Note the new parantheses! (rand()/(double)RAND_MAX
)
Now you are multiplying an integer by a fraction, so you are guaranteed not to overflow. But that introduces a new problem...
Promotion Is An Issue
But there's an even deeper problem. You divide an int by a double. When you do that the int
is promoted to a double
. A double is a floating-point number which basically means that it sacrifices precision in order to have a big range. That's probably what's biting you. As you get to bigger and bigger numbers both your ullong
and your llong
end up getting cast to the same value. This could be especially true if you overflowed your data type first (see above).
Uh oh
So, basically, everything about the PRNG you have presented is wrong.
Perhaps this is why John von Neumann said
Anyone who attempts to generate random numbers by deterministic means
is, of course, living in a state of sin.
And, sometimes, we pay for those sins.
How can I absolve myself?
C++11 provides some nice functionality. You can use it as follows
#include <iostream>
#include <random>
#include <limits>
int main(){
std::random_device rd; //Get a random seed from the OS entropy device, or whatever
std::mt19937_64 eng(rd()); //Use the 64-bit Mersenne Twister 19937 generator
//and seed it with entropy.
//Define the distribution, by default it goes from 0 to MAX(unsigned long long)
//or what have you.
std::uniform_int_distribution<unsigned long long> distr;
//Generate random numbers
for(int n=0; n<40; n++)
std::cout << distr(eng) << ' ';
std::cout << std::endl;
}
(Note that appropriately seeding the generator is difficult. This question addresses that.)
Related Topics
Special Simple Random Number Generator
How to Build Google's Protobuf in Windows Using Mingw
How to Get the Application Data Path in Windows Using C++
Same Random Numbers Every Time I Run the Program
Why Is the Size of Array as a Constant Variable Not Allowed in C But Allowed in C++
Is There a Limit of Stack Size of a Process in Linux
Arithmetic Right Shift Gives Bogus Result
How to Download a File with Winhttp in C/C++
Can Sfinae Detect Private Access Violations
Program Is Generating Same Random Numbers on Each Run
Why Doesn't C++ Move Construct Rvalue References by Default
Undefined Reference to 'Stdscr' While Using Ncurses
How Does C++ Preprocessors Work
How to Get the Maximum or Minimum Value in a Vector