2013-04-26 65 views
4

我处于编码环境中,我只能访问一些最基本的c函数。 #include'其他lib不可行。如何从c函数中获取较大的随机数rand()

在这个环境中,我可以调用rand(),它给我一个随机数,介于0到32767之间,包含在我的环境中(我认为)。下面的代码是正确的逻辑来获得一个较大的随机数,它是均匀分布的,如/ rand()?

rnum = rand() * (32767 + 1) + rand();

+2

由于均匀分布兰特是..确实高荣誉。你真的不能包含三十行BSD授权代码,并且包含arc4random或其他东西来正确地完成这项工作,或者读出/ dev/random? – 2013-04-26 23:23:07

+1

你应该说你的环境是什么,但它听起来很垃圾。请告诉我们您没有任何强烈的需求,这些数字是无法猜测的! – 2013-04-26 23:25:13

+1

许多嵌入式环境在可立即使用的库中受到限制。 – Marvo 2013-04-26 23:29:26

回答

5

rnum = (rand() << 15) | rand()可能会更快,但如果你需要高质量的随机数字,你应该寻找一个外部库。内置的随机函数通常只适用于最简单的应用程序。

+1

如果你曾经移植过RAND_MAX是一个非常有价值的平台,那么我会用'^'来代替'|',以避免问题。 – Cairnarvon 2013-04-26 23:33:05

+0

我会继续推荐[Mersenne Twister](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html)。我自己的[OneJoker](http://github.com/lcrocker/onejoker)库也有一个很好的发生器。 – 2013-04-27 00:09:57

+1

没有理由认为这会比OP的解决方案更快,事实上你的解决方案是错误的,因为<< 16被定义为乘以65536,而不是32768. – 2013-04-27 01:17:06

0

在使用ANY随机数发生器进行非平凡使用之前,应该对其进行广泛的测试。 Here是关于此主题的一篇文章的链接。

在二战时期布莱切利公园的破译者的各种历史中,都可以找到关于甚至是真随机数弱点的有趣背景。德国人和希特勒在战争的大部分时间都假定他们的密码因为被随机数字加密而不可破解,而英国人在几个月内完全破解了所有这些密码,因为德国实施“随机性”的各种弱点。许多代码在几天或几个月内被充分“扭曲”,即使没有被完全破坏,也足以被使用。

0

除了这里提出的其他优秀解决方案之外,您还可以在RAND_MAX中进行功率扩展,在用户定义的MY_RAND_MAX处截断,并丢弃将导致均匀性被破坏的解决方案。

int myrand(int MY_RAND_MAX) 
{ 
    int j = 0, num = 0; 

    // Generate digits for expansion in powers of RAND_MAX, up to acceptable range. 
    while (pow(RAND_MAX + 1, j) <= MY_RAND_MAX){ 
     num = num + rand() * (int)pow(RAND_MAX + 1, j); 
     j++; 
    } 

    //compute remainder to determine truncation 
    int remainder = ((int)pow(RAND_MAX + 1, j)) % (MY_RAND_MAX + 1); 

    // If number is within accepted bounds, mod and return 
    if (num <= ( (int)pow(RAND_MAX + 1, j) - remainder)){ 
     return (num % (MY_RAND_MAX + 1)); 

    // Else, if number generated exceeds allowed bounds, rerun method. 
    }else if (num > ( (int)pow(RAND_MAX + 1, j) - remainder)){ 
     return myrand(MY_RAND_MAX); 

    }else{ 
     exit(-1); 
    } 
} 

可以凭经验检查这种方法让你在给定范围内的统计均匀的输出。

我已经完成了几次不同范围的试验,每个试验的样本量都是100000,并且样本的方差和预期的方差至少达到了3个sig。每次都是图。

p.s.我不是一名编码员,而是一位最近学会编码的数学家/物理学家,所以我对代码质量的任何和所有反馈将不胜感激。