Jul 15, 2015

A fast random function for arduino/C++

Looking into random functions, there is a wide range of algorithms for pseudo-random number generators. (and a few ways to make them more random by varying the random seed. They vary in speed and quality distribution of randomness).I found an excellent page comparing several, with some comments on quality using standard analytic tools.*

The algorithm described below is short, fast, and doesn't require a values table. It is based on XOR shifting. I modified the example in the reference to make a self-contained function suitable for C++ or Arduino's Wiring.


// create a random integer from 0 - 65535
uint16_t rng(uint16_t seed) {
    static uint16_t y = 1;                // any value but 0
    if (seed != 0) y += (seed && 0x1FFF); // seeded with a different number
    y ^= y << 2;
    y ^= y >> 7;
    y ^= y << 7;
    return (y);
}

It works fine. I decided to compare its speed to the built-in function** in the arduino environment. To get a better value for the short times, I called it 8 successive times and averaged the result. Both are set to the range of a two-byte unsigned integer. My results show it as ~20 times faster, running on an 8-bit AVR micro at 16MHz (Teensy 2.0).
rng(0)               4.75 us
random(0,65535)     96.50 us
Usage is shown in the following snippet:


     n = rng(0);     // call random number generator function
     Serial.println(n);

which prints out something like   24871


*reference:
// good, fast random number generator xor-shift 
// based on a George Maraglia algorithm, 
// described and coded by Daniel Dunn

**Built-in Arduino random() function.

Find the complete example and source on github: Random Number Generator

(updated Mar 2019)