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)
rand() % 256
[or rand() & 0xFF
] - Daniel Fischer 2012-04-04 00:40
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.
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 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.
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
You could use unsigned char n = (unsigned char)(rand() & 0x00ff);
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));
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.
rand()%256
- mfontanini 2012-04-03 23:56