Generating random unsigned char values in C++

Go To StackoverFlow.com

3

I was wondering how to generate random unsigned char values. My idea;
rand()%255; since unsigned chars support between 0-255. I was wondering if this method could be improved(or is it the most legit way to do this)

2012-04-03 23:55
by Ali
Define "improve". BTW you should use rand()%256 - mfontanini 2012-04-03 23:56
Actually I should edit "improve" I was wondering if this was the right wa - Ali 2012-04-03 23:58
It is the right way. You could also use the random utilities provided in C++11, but this works - mfontanini 2012-04-03 23:58
It also depends on what you intend to use these values for. Are they going to be used as characters (e.g. to form a string that you are going to print or perform other string operations on)? Or are you using them just as an unsigned 8-bit integer - Raymond Chen 2012-04-04 00:01
I'm running the function in a loop to fill a matrix and most of the signs are "?". I've set the srand as 'srand((unsigned)time(NULL)); - Ali 2012-04-04 00:10
@rolandbishop : I hope you're not calling srand inside the loop.. - ildjarn 2012-04-04 00:14
Course not, just one time at the very beginning of the progra - Ali 2012-04-04 00:16
Just a note: 0-255 are 256 values, so you probably want rand() % 256 [or rand() & 0xFF] - Daniel Fischer 2012-04-04 00:40


4

A lot faster will be simple

unsigned char a = (unsigned char) rand();

Or you can do even 4 shifts of generated integer (on 32bit architecture) to four times reduce call to rand():

int a = rand();
unsigned char r1 = (unsigned char) a;
unsigned char r2 = (unsigned char) a >> 8;
unsigned char r3 = (unsigned char) a >> 16;
unsigned char r4 = (unsigned char) a >> 24;

Or something like that.

2012-04-04 00:04
by Petr Újezdský
since (unsigned char) up there, rand() function won't be going off limits right - Ali 2012-04-04 00:06
On platforms for which RAND_MAX is less than INT_MAX (e.g. VC++ where RAND_MAX is 32767), the high-order bytes will always be 0 - ildjarn 2012-04-04 00:06
The point still comes across. A simple check of whether this is the case beforehand would do the trick - chris 2012-04-04 01:16


4

The C++11 random number library is the best way if you want to stick to the standard library:

#include <random>

#include <functional>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <climits>

int main() {
    std::random_device r;
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};

    auto rand = std::bind(std::uniform_int_distribution<>(0, UCHAR_MAX),
                          std::mt19937(seed));

    std::generate_n(std::ostream_iterator<int>(std::cout," "), 25, rand);
}

The library provides some uniform random number engines and adapters to use with them to produce various distributions. Here we use a mt19937 engine (seeded using random_device (as a source of non-deterministic data if possible), and seed_seq to combine enough random data into a form suitable for filling out mt19937's internal state. Then we adapt the mt19937 using a uniform_int_distribution. By default this distribution will produce numbers uniformly distributed across the range supported by its template parameter, in this case unsigned char. So the function object we create will produce values in the range [0 256). Its results are demonstrated by writing out 25 values to the standard output.

There are distributions for other uses such as producing a normal distribution, simulating coin flips, or picking items out of a set with arbitrary weights (e.g. picking one of 3 items where the first is picked 50% of the time, the second is picked 10% of the time, and the third, 40% of the time).

Other engines are provided for different quality and performance characteristics. For example if you need a cryptographic random number generator, random_device may provide it if your implementation offers such capability.


Some additional resources.

2012-04-04 02:02
by bames53
Forgive me im asking a real silly question but this method would also work on g++ too right - Ali 2012-04-04 10:23
@rolandbishop Yeah, recent versions of gcc implement the C++11 random library. I tried it with gcc 4.5. - bames53 2012-04-04 14:58
uniform_int_distribution<unsigned char> gives compile-time error with Visual C++ 2013, so this idea doesn't look like portable one - Vitaliy 2015-01-14 13:38
@Vitaliy Thanks, I've fixed that problem - bames53 2015-01-14 16:20


1

You could use unsigned char n = (unsigned char)(rand() & 0x00ff);

2012-04-03 23:58
by John3136


1

A slightly cleaner way to do this the C++ way, using the random library would be:

#include <random>

int myseed = 1234;

std::default_random_engine rng(myseed);
std::uniform_int_distribution<int> rng_dist(0, 255);
char mychar = static_cast<unsigned char>(rng_dist(rng));
2013-06-13 23:39
by Riot


0

And you should be aware that rand() is one of the worst of the widely available random number generators, in terms of the quality (randomness) of its output. On UNIX-based systems, and some others, random() and lrand48() [and friends] are substantially better. For speed, the best way to use these is as described by @Pida, above, where you call only once for a word's worth of random bits. The word size depends on the random number generator you use.

2012-04-04 01:36
by DRVic