Особенности языка mql5, тонкости и приёмы работы - страница 135

 
Vict:

Вы очень внимательны, спасибо. Ошибся, не поставил скобки, так и пользовался бы "нечестной" функцией.

ЗЫ: внёс правки в исходное сообщение.

объясните пожалуйста, чем данная конструкция лучше банального rand()%max. 

ЗЫ я понял что вы имеете ввиду.
Ну тогда - а если 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:

Вы очень внимательны, спасибо. Ошибся, не поставил скобки, так и пользовался бы "нечестной" функцией.

ЗЫ: внёс правки в исходное сообщение.

Вы хоть осознаете, что если кто-то захочет воспользоваться вашей честной функцией и напишет get_rand(10), то это будет работать в 3276 раз медленнее, чем rand()%10

 
Nikolai Semko:

Ну тогда - а если max>32767? Ведь Ваша функция имеет тип uint, а генерирует максимум, что и rand(), т.е. 32767

тогда уж лучше использовать что-то вроде

А MathRand() возвращает int, что если кто-то будет ждать от неё число с шестью нулями? Расcчитываю на некоторый уровень публики. Вот, вы и сами знаете как получить > 32767.

Просто часто не задумываясь пишут rand()%3, а увидят моё сообщение и осознают что там будет сдвиг вероятностей.

Вы хоть осознаете, что если кто-то захочет воспользоваться вашей честной функцией и напишет get_rand(10), то это будет работать в 3276 раз медленнее, чем rand()%10

Ну да, очень медленно, на цикл из миллиона вызовов повторный вызов while случится около 300 раз. Если ваши программы состоят из голого for() в котором дёргается get_rand(), то это будет критично, наверное.

А вы осознаёте, что планировщик ос отбирает у вас кучу процессорного времени и несоизмеримо с rand() тормозит выполнение? Раз вы так торопитесь, то вам нужен какой-нибудь дос.

 
Vict:

А MathRand() возвращает int, что если кто-то будет ждать от неё число с шестью нулями? Расcчитываю на некоторый уровень публики. Вот, вы и сами знаете как получить > 32767.

Просто часто не задумываясь пишут rand()%3, а увидят моё сообщение и осознают что там будет сдвиг вероятностей.

Ну да, очень медленно, на цикл из миллиона вызовов повторный вызов while случится около 300 раз. Если ваши программы состоят из голого for() в котором дёргается get_rand(), то это будет критично, наверное.

А вы осознаёте, что планировщик ос отбирает у вас кучу процессорного времени и несоизмеримо с rand() тормозит выполнение? Раз вы так торопитесь, то вам нужен какой-нибудь дос.

Скорость функций критична при оптимизации. И дело не в планировщике и DOS.
 
Vict:

А MathRand() возвращает int, что если кто-то будет ждать от неё число с шестью нулями? Расcчитываю на некоторый уровень публики. Вот, вы и сами знаете как получить > 32767.

Просто часто не задумываясь пишут rand()%3, а увидят моё сообщение и осознают что там будет сдвиг вероятностей.

Ну да, очень медленно, на цикл из миллиона вызовов повторный вызов while случится около 300 раз. Если ваши программы состоят из голого for() в котором дёргается get_rand(), то это будет критично, наверное.

А вы осознаёте, что планировщик ос отбирает у вас кучу процессорного времени и несоизмеримо с 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;
  }

можно еще его убыстрить если перекодировать c ulong в uint, если не нужны большие числа( будет 3 rand() вместо пяти).

 
Nikolai Semko:

Да не бойтесь Вы признавать свои ошибки.  В этом нет ничего страшного и унизительного. Все мы ошибаемся. Это нормально.
Куда проще и полезней в плане восприятия сообщества сказать: "Да - был неправ. Спасибо." вместо попыток оправдываться. 

Ведь такой вариант работает гораздо быстрее и универсальнее:

можно еще его убыстрить если перекодировать c ulong в uint, если не нужны большие числа( будет 3 rand() вместо пяти).

Т.е. вас не смущает нечестность вашей реализации (по скорости, кстати, она будет много медленней)? Ну как знаете.

Зы: нечестность - генерация разных чисел диапазона с разной вероятностью.
 
Vict:

Т.е. вас не смущает нечестность вашей реализации (по скорости, кстати, она будет много медленней)? Ну как знаете.

Зы: нечестность - генерация разных чисел диапазона с разной вероятностью.
Вы это серьёзно?
 
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-долларовую купюру, чтобы найти закатившуюся под кровать 10 центовую монетку?
 
Nikolai Semko:
Т.е. Вы готовы поджечь 100-долларовую купюру, чтобы найти закатившуюся под кровать 10 центовую монетку?

Вы зря недооцениваете роль вероятностей.  На многомиллионных итерациях эти "закатившиеся монетки" выльются вам во вполне осязаемые цифры.  Тем более, ваш код очевидно нерационален при малых диапазонах (постоянно делать по пять вызовов 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
}
Причина обращения: