没有C库的最简单的随机数生成器?

时间:2018-09-26 09:23:17

标签: c random

我需要为Cortex M0 CPU固件添加一些随机性。随机性并不重要,但是速度很重要。

我测试了网上发现的两个功能。使用random(),我设法每31个时钟周期生成1个数字,而random_uint()在20个周期中生成1个数字。我的目标是小于10。我还可以使用哪些其他功能?

unsigned random() {
    unsigned b;

    b = t1 ^ (t1 >> 2) ^ (t1 >> 6) ^ (t1 >> 7);
    t1 = (t1 >> 1) | (~b << 31);

    b = (t2 << 1) ^ (t2 << 2) ^ (t1 << 3) ^ (t2 << 4);
    t2 = (t2 << 1) | (~b >> 31);

    return t1 ^ t2;
}

unsigned random_uint() {
    m_z = 36969 * (m_z & 65535) + (m_z >> 16);
    m_w = 18000 * (m_w & 65535) + (m_w >> 16);
    return (m_z << 16) + m_w;
}

3 个答案:

答案 0 :(得分:2)

好吧,我相信它是32位架构,最快的可能是LCG RNG。使用来自数字食谱的值,周期为2 32

inline uint32_t random_u32(uint32_t prev) {
    return prev*1664525U + 1013904223U; // assuming complement-2 integers and non-signaling overflow
}

int main() {
    auto seed = 1U;
    uint32_t = result;

    result = seed = random_u32(seed);
    result = seed = random_u32(seed);
    result = seed = random_u32(seed);
    ...
    return 0;
}

实际上,即使是更简单的版本,但周期更短,在C ++-11 minstd中使用的时间为2 31 -1。

inline uint32_t random_u32(uint32_t prev) {
    return prev*48271U;
}

种子不得为0,以134775813U之类的奇数开头

答案 1 :(得分:1)

static unsigned int g_seed;

// Used to seed the generator.           
inline void fast_srand(int seed) {
    g_seed = seed;
}

// Compute a pseudorandom integer.
// Output value in range [0, 32767]
inline int fast_rand(void) {
    g_seed = (214013*g_seed+2531011);
    return (g_seed>>16)&0x7FFF;
}

从这里:Faster than rand()?

答案 2 :(得分:1)

一些最快的生成器来自Xorshift发现的George Marsaglia系列,这是PRNG设计和PRNG测试的杰出贡献者。 Xorshift链接具有示例代码。给出的实现使用三个移位和三个XOR,这每个周期需要一个周期,而且很难被击败。