mql5语言的特点、微妙之处以及技巧 - 页 135

 
Vict:

你考虑得很周到,谢谢你。我犯了一个错误,我没有加括号,所以我应该用 "不公平 "的功能。

ZS:对原帖进行了更正。

请解释为什么这种结构比琐碎的rand()%max更好。

ZS:我明白你的意思。
那么--如果max>32767呢?你的函数是uint类型的,但生成的最大值与rand()相同,即32767。

你最好使用像这样的东西

ulong RandULong(ulong max=ULONG_MAX) {return(((ulong)rand()<<60)|((ulong)rand()<<45)|((ulong)rand()<<30)|((ulong)rand()<<15)|(ulong)rand())%max;}
 
Vict:

你考虑得很周到,谢谢你。我犯了一个错误,没有放括号,所以我会用 "不公平 "功能。

ZS:对原帖进行了更正。

你是否意识到,如果有人想使用你的诚实函数并写出get_rand(10),它的工作速度会比rand()%10慢3276倍

 
Nikolai Semko:

那么--如果max>32767呢?毕竟,你的函数是uint类型的,但生成的最大值是rand(),即32767。

你最好使用类似

而MathRand()返回的是int,如果有人希望从中得到一个有六个零的数字,怎么办?算是在某种程度上的公开。在这里,你自己知道如何获得>32767。

他们只是经常不假思索地写rand()%3,然后看到我的信息,意识到这将改变概率。

你是否意识到,如果有人想使用你的诚实函数并写出get_rand(10),它的工作速度会比rand()%10慢3276倍

是的,非常慢,对于一百万次调用的周期,回调会发生300次左右。如果你的程序由光秃秃的for()组成,其中get_rand()在蠢蠢欲动,那就很关键了,我想。

而且你是否意识到,操作系统调度程序占用了大量的CPU时间,并使执行速度与rand()不相称?如果你如此匆忙,你需要某种剂量。

 
Vict:

而MathRand()返回的是int,如果有人期望从中得到一个有六个零的数字,怎么办?我指望着一定程度的公众。在这里,你自己知道如何获得>32767。

他们只是经常不假思索地写rand()%3,然后看到我的信息,意识到会有一个概率转移。

嗯,是的,非常慢,对于一个百万次调用的周期,回调会发生300次左右。如果你的程序由光秃秃的for()组成,其中get_rand()在蠢蠢欲动,那就很关键了,我想。

而且你是否意识到,操作系统调度器占用了大量的CPU时间,并使执行速度与rand()不成比例地降低?如果你如此匆忙,你需要某种剂量。

函数的速度在优化中是至关重要的。而且这与调度器和DOS无关。
 
Vict:

而MathRand()返回的是int,如果有人期望从中得到一个有六个零的数字,怎么办?我指望着一定程度的公众。在这里,你自己知道如何获得>32767。

他们只是经常不假思索地写rand()%3,看到我的信息后,才意识到这将转移概率。

是的,非常慢,对于一百万次调用的周期,回调会发生300次左右。如果你的程序由光秃秃的for()组成,而get_rand()在其中蠢蠢欲动,那就很关键了,我想。

而且你是否意识到,操作系统调度程序占用了大量的CPU时间,并使执行速度与rand()不成比例地降低?如果你如此匆忙,你需要某种剂量。

不要害怕承认你的错误,这没有什么可怕或羞辱的。我们都会犯错。这很正常。
就社区的看法而言,说 "是的,我错了 "要容易得多,也更有用。谢谢你。"而不是试图找借口。

这样做的速度更快、更灵活。

ulong randUlong(ulong max=ULONG_MAX)
  {
   static bool f=true;
   if(f) {f=false; srand(GetTickCount());}
   return(((ulong)rand()<<60)|((ulong)rand()<<45)|((ulong)rand()<<30)|((ulong)rand()<<15)|(ulong)rand())%max;
  }

如果你不需要大的数字(你需要3个rand()而不是5个),你可以把它从ulong重新编码为uint,这样可以加快速度。

 
Nikolai Semko:

不要害怕承认你的错误--这没有什么可怕和羞辱的。我们都会犯错。没关系的。
说 "是的,我错了 "要容易得多,对社区也更有帮助。谢谢你。"而不是试图为自己辩解。

毕竟,这个选项的工作速度更快,更普遍。

如果你不需要大数字,也可以通过从ulong到uint的重新编码来加快速度(3个rand()而不是5个)。

所以你不会因为你的实施不公平而感到困惑(顺便说一下,就速度而言,它将会慢得多)?随你便吧。

Zy:不诚实--以不同的概率产生不同的范围数字。
 
Vict:

所以你没有被你的实施的不公平所迷惑(顺便说一下,在速度上会慢很多)?随你便吧。

Zy:不诚实是以不同的概率产生不同的范围数字。
你是认真的吗?
 
Why do people say there is modulo bias when using a random number generator?
Why do people say there is modulo bias when using a random number generator?
  • 2012.06.11
  • user1413793user1413793 5,32651933
  • stackoverflow.com
I have seen this question asked a lot but never seen a true concrete answer to it. So I am going to post one here which will hopefully help people understand why exactly there is "modulo bias" when using a random number generator, like in C++.
 
所以你愿意放火烧掉一张100美元的钞票来寻找滚在床底下的一角钱?
 
Nikolai Semko:
所以你愿意放火烧掉一张100美元的钞票来寻找滚在床底下的一角钱?

你不应该低估概率的作用。 在数百万次的迭代中,这些 "滚动的便士 "将使你付出相当具体的数字。 此外,你的代码在小范围内显然是不合理的(不断地对rand()进行五次调用正是 "烧纸条")。

六个月前,这个话题已经在论坛上讨论过了,我提出了这个方案。

关于交易、自动交易系统和测试交易策略的论坛

如何在N个深度范围内获得一个随机数?

Alexey Navoykov, 2018.12.31 01:25

我的最后一个代码被证明是不正确的。我在数字上制造了太多的麻烦。 这里是正确的变体,同时也是更简洁的。

ulong RandomLong(ulong range)
{
 #define _MAXRND(range, rnd_range)  ((rnd_range) - ((rnd_range)-range)%range - 1) 
 #define _RND (ulong)rand()
  ulong rnd, max, const bit=1;
  if (range <= bit<<15) { if (!range) return0;  max=_MAXRND(range, 1<<15);  while((rnd=_RND) > max);  return rnd%range; }
  if (range <= bit<<30) { max=_MAXRND(range, bit<<30);  while((rnd=(_RND | _RND<<15)) > max);  return rnd%range; }
  if (range <= bit<<45) { max=_MAXRND(range, bit<<45);  while((rnd=(_RND | _RND<<15 | _RND<<30)) > max);  return rnd%range;  }
  if (range <= bit<<60) { max=_MAXRND(range, bit<<60);  while((rnd=(_RND | _RND<<15 | _RND<<30 | _RND<<45)) > max);  return rnd%range; }
                  else  { max=_MAXRND(range, bit<<64);  while((rnd=(_RND | _RND<<15 | _RND<<30 | _RND<<45 | _RND<<60)) > max);  return rnd%range; }
 #undef _RND               
 #undef _MAXRND
}