Standard rand()
function gives numbers not big enough for me: I need unsigned long long
ones. How do we get really big random numbers? I tried modifying a simple hash function but it's too big, takes too long to run and never produces numbers which are less than 1e5!!

- 43,482
- 10
- 63
- 98
-
1How much "BIG" numbers you want? – shauryachats Jan 23 '15 at 17:50
-
2How about using rand() to get sets of random bits, and populating each `int`-wide number of bits at a time into the `unsigned long long` using bit masks. – Eric J. Jan 23 '15 at 17:51
-
1"never produces numbers which are less than 1e5" - how have you defined "never"? It would be expected that perfectly random numbers wouldn't occupy that range very often, given the full range you're asking for. – Mark Ransom Jan 23 '15 at 17:51
-
4how about ditching `rand()` and using some of the better RNGs c++ provides http://en.cppreference.com/w/cpp/numeric/random – genisage Jan 23 '15 at 17:51
-
@ShauryaChats, VERY big, much more than 1e7 – ForceBru Jan 23 '15 at 17:54
-
Have you seen http://stackoverflow.com/questions/8120062/generate-random-64-bit-integer? – David Ranieri Jan 23 '15 at 17:55
-
@AlterMann, I'm just not sure if these numbers fit into unsigned long long – ForceBru Jan 23 '15 at 17:56
6 Answers
You can easily do this with std::uniform_int_distribution<unsigned long long>
.
Simple example code (taken from here, modified to use unsigned long long
):
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<unsigned long long> dis(lowerBorder, upperBorder);
for (int n=0; n<10; ++n)
std::cout << dis(gen) << ' ';
std::cout << '\n';
}
Note that the seeding of the mersenne twister as done here for demo purposes is not perfect, for example see here.

- 49,044
- 25
- 144
- 182
-
1
-
-
@Alexandru No, that will not improve randomness. You can try if it improves speed on your environment, that might potentially work. – Baum mit Augen Dec 20 '17 at 12:41
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.

- 32,319
- 7
- 89
- 113
-
4Be really weary of this. It may seem reasonable but the numbers it produces may not (actually, probably will not) pass many statistical tests of randomness. – Nik Bougalis Jan 23 '15 at 18:11
-
Nice, but can you explain why `r & 0xFFFFFFFFFFFFFFFFULL;`?, it seems a NOOP – David Ranieri Jan 23 '15 at 18:16
-
1@AlterMann As I said, `long long` might be larger than 64 bits. If it is 64 bits, the compiler should make it a noop. – nwellnhof Jan 23 '15 at 18:17
-
in most modern compilers RAND_MAX == INT_MAX with 32-bit int, so only `return rand() << 32 | rand();` is enough – phuclv Jan 23 '15 at 18:21
-
@LưuVĩnhPhúc Even if `RAND_MAX == INT_MAX`, this wouldn't work since `rand()` only returns 31 random bits. – nwellnhof Jan 23 '15 at 18:23
-
I forgot that it doesn't return a negative value. But even in that case you only need 3 `rand` calls, not 5 – phuclv Jan 23 '15 at 18:27
-
2@LưuVĩnhPhúc MSVC (which has a reasonable market share) has `#define RAND_MAX 0x7fff` – Weather Vane Jan 23 '15 at 18:28
-
1@NikBougalis can you provide a citation or an example of a test that this would fail on (that rand() by itself would pass) – Foon Mar 30 '15 at 18:58
-
@Foon ask yourself if every possible `unsigned long long` number can be generated from `llrand` and whether some numebrs are more or less likely. Assume that `rand() & 0x7FFF` is evenly distributed for the purposes of this experiment. – Nik Bougalis Mar 30 '15 at 19:12
-
You can test it with a suite like [dieharder](http://www.phy.duke.edu/~rgb/General/dieharder.php). I'll bet it will fail several of the tests. – David Schwartz Mar 30 '15 at 19:25
-
2@NikBougalis Still not seeing issue; assuming rand() is uniformly distributed, not seeing any number that can't be generated or any that would be generated more or less often. With that said, ran this against dieharder 3.31.1; there were two "good" tests that came back weak [not failed] (as opposed to just using the output of rand(), which had many failures, presumably due to rand() not return 32 bits of randomness at a time, or with uchar x = rand() % 256 and outputting 8 bits at a time; only 1 suspect test came back weak (rest passed) – Foon Mar 31 '15 at 01:49
-
@DavidSchwartz for the record, the two that came back weak were an rgb_lagged_sum for ntuple=28 and one of the sts_serials for ntuple=8. This was using a srand(1) on a 64bit Linux box. – Foon Mar 31 '15 at 01:50
-
Ack, in the interest of not clogging this answer any more, posted this as a follow on question: http://stackoverflow.com/questions/29366721/how-do-i-interpret-the-results-from-dieharder-for-great-justice Note that when I re-ran the tests, the 8 bit at a time version came back with one weakness; not sure if I missed that last time or if something changed between runs that I'm missing – Foon Mar 31 '15 at 10:43
If you want just to produce unsigned long long from value returned by rand() and do not care about the characteristics of the result consider the following function that must be compiler version and platform independent (because no "magic numbers" are used):
// this header has RAND_MAX value
#include <stdlib.h>
// and this header has ULLONG_MAX
#include <limits.h>
unsigned long long ullrand()
// Produces pseudo-random numbers from 0 to ULLONG_MAX
// by filling all bits of unsigned long long integer number
// with bits of several "small" integer numbers generated by rand()
{
unsigned long long myrndnum = 0; // at the beginning just zero
unsigned long long counter = ULLONG_MAX; // at the beginning we have all bits set as 1
// ... and while at least one bit is still set to 1
while(counter > 0) {
myrndnum = (myrndnum * (RAND_MAX + 1)) + rand(); // fill some bits from rand()
counter /= (RAND_MAX + 1); // decrease number of 1-bits in counter
}
// Return the result
return myrndnum;
}
But if you want some sequence of random numbers with certain predetermined characteristics, you should look in some specific guides or math books. E.g. https://www.gnu.org/software/gsl/manual/html_node/Random-number-generator-algorithms.html
You didn't ask for a specific OS and the answers here are really good, but on Linux (and probably on other OSes too) you can also read from a random device.
Example:
#include <stdio.h>
#include <assert.h>
#define RANDDEV "/dev/urandom"
unsigned long long bigrand(void) {
FILE *rdp;
unsigned long long num;
rdp = fopen(RANDDEV, "rb");
assert(rdp);
assert(fread(&num, sizeof(num), 1, rdp) == 1);
fclose(rdp);
return num;
}
Written on mobile, may have bugs. :P

- 3,538
- 1
- 24
- 35
-
1Maybe you should turn off buffering, or use read(), to avoid wasting random bytes? – potrzebie Jan 24 '15 at 22:49
You can also use the boost library (taken from link):
#include <ctime> // std::time
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/generator_iterator.hpp>
int main()
{
long long my_min = 1;
long long my_max = 1e5;
boost::mt19937 generator(static_cast<unsigned int>(std::time(0)));
boost::variate_generator<boost::mt19937&, boost::uniform_real<> >
die_gen(generator, boost::uniform_real<> (my_min, my_max));
boost::generator_iterator<boost::variate_generator<boost::mt19937&, boost::uniform_real<> > > die(&die_gen);
std::cout<<"Generated random numbers: \n";
for (int i=0; i <10 ; i++)
{
std::cout<< static_cast<long long>(*die++) << std::endl;
}
return 0;
}

- 347
- 3
- 13
try this:
long N=1000000;
long randNumber;
for(long i=0;i<N;i++)
randNumber=i+rand()

- 7
- 2
-
2While this code may answer the question, it would be better to include some _context_, explaining _how_ it works and _when_ to use it. Code-only answers are not useful in the long run. – Benjamin W. Mar 28 '16 at 18:38
-
2This is a terrible method to generate random numbers. It's slow, badly distributed, and causes undefined behavior due to signed overflow. – interjay Feb 13 '17 at 16:39