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