C语言 如何在没有 rand() 函数的情况下生成随机数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7602919/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I generate random numbers without rand() function?
提问by AnkurVj
I want to generate (pseudo) random numbers between 0 and some integer. I don't mind if they aren't too random. I have access to the current time of the day but not the rand function. Can anyone think of a sufficiently robust way to generate these? Perhaps, discarding some bits from time of day and taking modulo my integer or something?
我想生成 0 和某个整数之间的(伪)随机数。我不介意它们不是太随机。我可以访问当天的当前时间,但不能访问 rand 函数。谁能想到一种足够强大的方法来生成这些?也许,从一天中的某个时间丢弃一些位并取模我的整数之类的?
I am using c.
我正在使用 c。
回答by Roddy
If you're after an ultra-simple pseudo-random generator, you can just use a Linear Feedback shift Register.
如果您追求的是超简单的伪随机发生器,则可以使用Linear Feedback shift Register。
The wikipedia article has some code snippets for you to look at, but basically the code for a 16-bit generator will look something like this (lightly massaged from that page...)
维基百科文章有一些代码片段供您查看,但基本上 16 位生成器的代码看起来像这样(从该页面轻轻按摩......)
unsigned short lfsr = 0xACE1u;
unsigned bit;
unsigned rand()
{
bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1;
return lfsr = (lfsr >> 1) | (bit << 15);
}
回答by Dennis
For "not too random" integers, you could start with the current UNIX time, then use the recursive formula r = ((r * 7621) + 1) % 32768;. The nth random integer between 0(inclusive) and M(exclusive) would be r % Mafter the nth iteration.
对于“不太随机”的整数,您可以从当前 UNIX 时间开始,然后使用递归公式r = ((r * 7621) + 1) % 32768;。0(inclusive) 和M(exclusive)之间的第 n 个随机整数将r % M在第 n 次迭代之后。
This is called a linear congruential generator.
这称为线性同余生成器。
The recursion formula is what bzip2uses to select the pivot in its quicksort implementation. I wouldn't know about other purposes, but it works pretty well for this particular one...
递归公式是bzip2在其快速排序实现中用来选择枢轴的。我不知道其他目的,但它对这个特定的目的非常有效......
回答by unwind
Look at implementing a pseudo-random generator (what's "inside" rand()) of your own, for instance the Mersenne twisteris highly-regarded.
看看实现rand()你自己的伪随机生成器(什么是“内部” ),例如 梅森扭曲器是备受推崇的。
回答by Rajan saha Raju
#include <chrono>
int get_rand(int lo, int hi) {
auto moment = std::chrono::steady_clock::now().time_since_epoch().count();
int num = moment % (hi - lo + 1);
return num + lo;
}
回答by HaSeeB MiR
The smallest and simple random generatorwhich work with rangesis provided below with fully working example.
下面提供了使用范围的最小且简单的随机生成器,并提供了完整的工作示例。
unsigned int MyRand(unsigned int start_range,unsigned int end_range)
{
static unsigned int rand = 0xACE1U; /* Any nonzero start state will work. */
/*check for valid range.*/
if(start_range == end_range) {
return start_range;
}
/*get the random in end-range.*/
rand += 0x3AD;
rand %= end_range;
/*get the random in start-range.*/
while(rand < start_range){
rand = rand + end_range - start_range;
}
return rand;
}
int main(void)
{
int i;
for (i = 0; i < 0xFF; i++)
{
printf("%u\t",MyRand(10,20));
}
return 0;
}
回答by pmg
If you're not generating your numbers too fast (*1) and your upper limit is low enough (*2) and your "time of day" includes nanoseconds, just use those nanoseconds.
如果您生成的数字不是太快 (*1) 并且您的上限足够低 (*2) 并且您的“一天中的时间”包括纳秒,请使用这些纳秒。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int nanorand(void) {
struct timespec p[1];
clock_gettime(CLOCK_MONOTONIC, p);
return p->tv_nsec % 1000;
}
int main(void) {
int r, x;
for (;;) {
r = nanorand();
do {
printf("please type %d (< 50 quits): ", r);
fflush(stdout);
if (scanf("%d", &x) != 1) exit(EXIT_FAILURE);
} while (x != r);
if (r < 50) break;
}
puts("");
return 0;
}
And a sample run ...
和一个示例运行...
please type 769 (< 50 quits): 769 please type 185 (< 50 quits): 185 please type 44 (< 50 quits): 44
(*1) if you're using them interactively, one at a time
(*2) if you want numbers up to about 1000
(*1) 如果您以交互方式使用它们,则一次一个
(*2) 如果您想要最多约 1000 个数字
回答by Staven
The only "robust" (not easily predictable) way of doing this is writing your own pseudo-random number generator and seeding it with the current time. Obligatory wikipedia link: http://en.wikipedia.org/wiki/Pseudorandom_number_generator
这样做的唯一“强大”(不容易预测)的方法是编写您自己的伪随机数生成器并使用当前时间为其播种。强制性维基百科链接:http: //en.wikipedia.org/wiki/Pseudorandom_number_generator
回答by Dominic
You can get the "Tiny Mersenne Twister" here: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index.html
你可以在这里得到“Tiny Mersenne Twister”:http: //www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index.html
it is pure c and simple to use. E.g. just using time:
它是纯 C 语言,使用简单。例如只使用时间:
#include "tinymt32.h"
// And if you can't link:
#include "tinymt32.c"
#include <time.h>
#include <stdio.h>
int main(int argc, const char* argv[])
{
tinymt32_t state;
uint32_t seed = time(0);
tinymt32_init(&state, seed);
for (int i=0; i<10; i++)
printf("random number %d: %u\n", i, (unsigned int)tinymt32_generate_uint32(&state));
}
回答by Kapil
import java.io.*;
public class random{
public static class p{
}
static long reg=0;
static long lfsr()
{
if(reg==0)
{
reg=145896027340307l;
}
long bit=(reg>>0^reg>>2^reg>>3^reg>>5)&1;
reg=reg>>1|bit<<62;
return reg;
}
static long getRand()
{
String s=String.valueOf(new p());
//System.out.println(s);
long n=0;
lfsr();
for(int i=0;i<s.length();i++)
{
n=n<<8|+s.charAt(i);
}
System.out.print(n+" "+System.currentTimeMillis()+" "+reg+" ");
n=n^System.currentTimeMillis()^reg;
return n;
}
public static void main(String args[])throws IOException
{
for(int i=0;i<400;i++)
{
System.out.println(getRand());
}
}
}
}
This is a random number generator where it is guaranteed that the sequence never repeats itself. I have paired time with object value (randomly put by java) with LFSR.
这是一个随机数生成器,可以保证序列永远不会重复。我已将时间与对象值(由 java 随机放置)与 LFSR 配对。
Advantages:
好处:
- The sequence doesn't repeat itself
- The sequence is new on every run
- 序列不会自我重复
- 每次运行的序列都是新的
Disadvantages:
缺点:
- Only compatible with java. In C++, new object that is created is same on every run.
- But there too time and LFSR parameters would put in enough randomness
- It is slower than most PRNGs as an object needs to be created everytime a number is needed
- 仅与 java 兼容。在 C++ 中,每次运行时创建的新对象都是相同的。
- 但是时间和 LFSR 参数也会带来足够的随机性
- 它比大多数 PRNG 慢,因为每次需要一个数字时都需要创建一个对象
回答by Awi
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int main()
{
unsigned int x,r,i;
// no of random no you want to generate
scanf("%d",&x);
// put the range of random no
scanf("%d",&r);
unsigned int *a=(unsigned int*)malloc(sizeof(unsigned int)*x);
for(i=0;i<x;i++)
printf("%d ",(a[i]%r)+1);
free(a);
getch();
return 0;
}

