Какая разница между функциями rand() и random()?

Однажды мой учитель научил меня использовать функции randomize() и random() для генерации псевдослучайных чисел в С++ Builder. Теперь я предпочитаю работать в VS 2012, но когда я пытался использовать эти функции, там говорится, что "идентификатор не найден", даже когда я добавил #include <stdlib.h>. Через некоторое время в Гуглинг я обнаружил, что есть также функции rand() и srand(). В чем разница между ними и какой из них лучше использовать?

Ответ 1

randomize() и random() не входят в стандартную библиотеку. Возможно, ваш учитель написал функции с этими именами для использования в вашем классе, или, может быть, вы действительно имеете в виду random() и srandom(), которые являются частью POSIX и недоступны в Windows. rand() и srand() являются частью стандартной библиотеки и будут предоставляться любой стандартной совместимой реализацией С++.


Вам следует избегать rand() и srand() и использовать новую библиотеку С++ 11 <random>. <random> был добавлен как часть стандарта С++ 11 (и VS2012 его предоставляет).

Видео, объясняющее почему: rand() Считается вредным

  • rand() обычно является pRNG низкого качества и не подходит для приложений, требующих разумного уровня непредсказуемости. <random> предоставляет различные двигатели с различными характеристиками, подходящими для разных случаев использования.

  • Преобразование результатов rand() в число, которое вы можете использовать напрямую, обычно зависит от кода, который трудно читать и легко ошибается, тогда как использование <random> распределений легко и создает читаемый код.

  • Общие методы генерации значений в данном распределении с использованием rand() дополнительно уменьшают качество сгенерированных данных. % обычно смещает данные, а деление с плавающей запятой все еще создает неравномерные распределения. <random> дистрибутивы более высокого качества, а также более читаемые.

  • rand() полагается на скрытый глобальный ресурс. Среди других проблем это означает, что rand() не является потокобезопасным. Некоторые реализации обеспечивают гарантии безопасности потоков, но это не стандарт. Двигатели, предоставляемые <random>, инкапсулируют состояние pRNG как объекты со значениями семантики, что позволяет гибко управлять состоянием.

  • srand() разрешает только ограниченный диапазон семян. Двигатели в <random> могут быть инициализированы с использованием семенных последовательностей, которые позволяют получить максимально возможные данные семян. seed_seq также реализует общую разминку pRNG.


пример использования <random>:

#include <iostream>
#include <random>

int main() {
  // create source of randomness, and initialize it with non-deterministic seed
  std::random_device r;
  std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
  std::mt19937 eng{seed};

  // a distribution that takes randomness and produces values in specified range
  std::uniform_int_distribution<> dist(1,6);

  for (int i=0; i<100; ++i) {
    std::cout << dist(eng) << '\n';
  }
}

Ответ 2

Хотя есть (очевидно, выше) люди, которые будут утверждать с религиозным рвением, что rand() является плохим и случайным(), нет, оказывается, что ваш пробег может отличаться. Здесь gcc ответ на вопрос "Какая разница...", предоставленная gcc-версией stdlib.h(выделено мной):

/* Это функции, которые на самом деле делают вещи. random', srandom ',  initstate' and setstate '- это функции из BSD Unices.  Функции rand' and srand требуются стандартом ANSI.   Мы предоставляем оба интерфейса тому же генератору случайных чисел./ /Возвращает случайное длинное целое число от 0 до RAND_MAX включительно. */

Ответ 3

Похоже, вы использовали функции C-стиля, хотя ваш вопрос помечен как С++. Кроме того, stdlib.h - это заголовочный файл из стандартной библиотеки C. Там нет таких функций random() и randomize() в стандартной библиотеке C. Стандартная библиотека C имеет rand() и srand().

Если вы использовали random() или что-то вроде этого через stdlib.h, это должно было быть нестандартным расширением библиотеки в компиляторе Borland.

Итак, если вы хотите придерживаться стандартных функций C-стиля, это будет, опять же, rand() и srand(). Но если вы пишете на С++, у вас могут быть лучшие (и более подходящие) варианты в стандартной библиотеке С++.

Ответ 4

srand() - реализация библиотеки C Standard для посева генератора случайных чисел (псевдо). rand() - генератор случайных чисел (псевдо) в стандартной библиотеке C.

В файле <random> С++ реализован новый (псевдо) генератор случайных чисел, в котором используется множество различных движков: http://en.cppreference.com/w/cpp/numeric/random

Ответ 5

Функции rand() и random() либо определяются POSIX с по крайней мере POSIX.1-2001.

В более старых реализациях rand() и в текущих реализациях в разных системах младшие разряды намного менее случайны, чем бит более высокого порядка.

Когда доступно, random() не страдает от этой проблемы.

В добавлении, в современной версии rand() используется тот же генератор случайных чисел, что и random(). Поэтому rand() может быть правильным, но он не гарантируется.

Итак, всегда используйте random() вместо rand(). Если random() недоступно в вашей операционной системе, попросите разработчиков операционной системы предоставить новую реализацию API стандартов (стандарт 2001 года уже достаточно велик, чтобы ожидать, что какая-либо система предоставит его).

Ответ 6

Я не знаком с randomize() и random(), но они не являются частью стандартной библиотеки. Вам не следует использовать rand(), это видео объясняет, почему использование rand() считается вредным.

Вы должны использовать случайный заголовок, введенный в С++ 11, вот пример, использующий как std:: uniform_real_distribution и std:: uniform_int_distribution:

#include <iostream>
#include <random>

int main()
{
    std::random_device rd;

    std::mt19937 e2(rd());

    std::uniform_int_distribution<> dist(1, 6);
    std::uniform_real_distribution<> distReal(1, 6);

    for( int i = 0 ; i < 10; ++i )
    {
       std::cout << dist(e2) << ",";
    }
    std::cout << std::endl ;

    for( int i = 0 ; i < 10; ++i )
    {
       std::cout << distReal(e2) << ",";
    }
    std::cout << std::endl ;

    return 0 ;
}

Ответ 7

Это обход, основанный на использовании случайных чисел вне С++.

Это оригинальная программа на C, скопированная с " http://www.programmingsimplified.com/" Эта программа не запускается, потому что "temp1 = 1 + random (588);"                                                                                "temp2 = 1 + random (380);" заявления не работают. "random" не является функцией graphics.h, conio.h или stdlib.h Это не работает, если вы включили random.h. Ниже приведен список действий для случайной функции.

#include<graphics.h>
#include<conio.h>
#include<stdlib.h>
main()
{
   int gd = DETECT, gm, area, temp1, temp2, left = 25, top = 75;
   void *p;
   initgraph(&gd,&gm,"C:\\TC\\BGI");

   setcolor(YELLOW);
   circle(50,100,25);
   setfillstyle(SOLID_FILL,YELLOW);
   floodfill(50,100,YELLOW);

   setcolor(BLACK);
   setfillstyle(SOLID_FILL,BLACK);
   fillellipse(44,85,2,6);
   fillellipse(56,85,2,6);

   ellipse(50,100,205,335,20,9);
   ellipse(50,100,205,335,20,10);
   ellipse(50,100,205,335,20,11);

   area = imagesize(left, top, left + 50, top + 50);
   p = malloc(area);

   setcolor(WHITE);
   settextstyle(SANS_SERIF_FONT,HORIZ_DIR,2);
   outtextxy(155,451,"Smiling Face Animation");

   setcolor(BLUE);
   rectangle(0,0,639,449);

   while(!kbhit())
   {
      temp1 = 1 + random ( 588 );
      temp2 = 1 + random ( 380 );

      getimage(left, top, left + 50, top + 50, p);
      putimage(left, top, p, XOR_PUT);
      putimage(temp1 , temp2, p, XOR_PUT);
      delay(100);
      left = temp1;
      top = temp2;
   }

   getch();
   closegraph();
   return 0;
}

Случайные числа генерируются с помощью простого макроса MS Excel, указанного здесь:

Sub Macro1()
Dim i
For i = 1 To 400
Randomize

Range("a" & i) = Int(Rnd * 588) + 1
Range("b" & i) = Int(Rnd * 380) + 1

Next i
End Sub

Это генерирует 2 столбца случайных чисел. Каждый столбец копируется и вставляется в его собственный *.txt файл, т.е. rnd1.txt и rnd2.txt, и помещается в каталог, в котором они могут быть доступ к которым осуществляется программой С++. Замените "c:\PATH\rnd1.txt" и "C:\PATH\rnd2.txt" с правильным путем.

#include<iostream>
#include<fstream> 
#include<graphics.h>

using namespace std;
 int i,j,k;
int main(int argc, char** argv) {
   std::ifstream infile1;
   infile1.open("c:\\PATH\\rnd1.txt",ios::in);
   ifstream infile2;
   infile2.open("c:\\PATH\\rnd2.txt",ios::in);
   int gd = DETECT, gm, area, temp1, temp2, left = 25, top = 75;
   void *p;
   initgraph(&gd,&gm,"C:\\TC\\BGI");

   setcolor(YELLOW);
   circle(50,100,25);
   setfillstyle(SOLID_FILL,YELLOW);
   floodfill(50,100,YELLOW);

   setcolor(BLACK);
   setfillstyle(SOLID_FILL,BLACK);
   fillellipse(44,85,2,6);
   fillellipse(56,85,2,6);

   ellipse(50,100,205,335,20,9);
   ellipse(50,100,205,335,20,10);
   ellipse(50,100,205,335,20,11);

   area = imagesize(left, top, left + 50, top + 50);
   p = malloc(area);

   setcolor(WHITE);
   settextstyle(SANS_SERIF_FONT,HORIZ_DIR,2);
   outtextxy(155,451,"Smiling Face Animation ");

   setcolor(BLUE);
   rectangle(0,0,639,449);

   while(!kbhit())
   {
      infile1 >> j;
      temp1 = j;
      infile2 >> k;
      temp2 = k;
      if(infile2.eof()) {
       closegraph();
       void close();
       return 0;
        }                
      getimage(left, top, left + 50, top + 50, p);
      putimage(left, top, p, XOR_PUT);
      putimage(temp1 , temp2, p, XOR_PUT);
      delay(100);
      left = temp1;
      top = temp2;
      }

      }

Эта программа будет работать около 40 секунд, а затем прекратится.