LINUX.ORG.RU

Случайные числа


0

0

Понадобилась портабельная Ц/Ц++ библиотека в виде одного h/c файла, которая способна генерировать достаточно случайные числа. Пара srand, rand()%2 мне выдает с глазу не особо случайный ряд, особенно когда надо множество разделить случайно на две категории.

★★★★★

CRand::CRand()
{
	char name[] = "/dev/urandom";
	fd = open( name, O_RDONLY );
}

CRand::~CRand()
{
	if( fd > 0 ) close( fd );
	fd = 0;
}

int CRand::Rand()
{
	int ret = 0;
	read( fd, &ret, 4 );
	return (ret&0xFFFF);
}

int CRand::Rand( int a, int b )
{
	int ret = 0;
//	if( b == 1 ) return 1;
//	if( b == 0 ) return 0;
	read( fd, &ret, 1*sizeof(int));
	return (a+(ret&0xFFFF)%(b-a+1));
}

Вполне адекватный вариант...
Уж заголовочный , думаю, напишешь как тебе будет удобно...
Только вот с портабельностью тут плохо.
В каком масштабе нужна переносимость?

Stahl ★★☆
()
Ответ на: комментарий от Stahl

меня устроит, а вот научрука с вендой может и не особо :/ если бы все имели urandom у меня бы такой проблемы не возникло.

Pi ★★★★★
() автор топика
Ответ на: комментарий от Stahl

правильно, герои не боятся системных вызовов!

dilmah ★★★★★
()

void CRnd::Seed(int seed) {
        m_seed  = seed;
}

int CRnd::Int(int min, int max) {
        m_seed  = 214013 * m_seed + 2531011;
        return min + (m_seed ^ m_seed >> 15) % (max - min + 1);
}

float CRnd::Float(float min, float max) {
        m_seed  = 214013 * m_seed + 2531011;
        return min + (m_seed >> 16) * (1.0f / 65535.0f) * (max - min);
}

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

хм... а из каких соображений получились константы?

Stahl ★★☆
()
Ответ на: комментарий от anonymous

предлагаешь так?:
CRand::~CRand()
{
	if( fd >= 0 ) close( fd );
}

Это деструктор и вообще-то тут fd="что-то там" вообще не надо.
Да и, думаю, ситуация, когда fd==0 невероятна.

Хотя такой вариант строже и правильней.

Stahl ★★☆
()
Ответ на: комментарий от Stahl

> Да и, думаю, ситуация, когда fd==0 невероятна.

int main(void) {
	int fd;

	close(0);
	close(1);
	close(2);

	fd = open("/dev/urandom", O_RDONLY);
	close(fd);
	return fd;
}

vsb@vsb-desktop:~/tmp$ ./a.out 
vsb@vsb-desktop:~/tmp$ echo $?
0

Legioner ★★★★★
()

MIRACL возьми.. Впрочем оно все там такое случайное.. Может лучше хардварный генератор купить? Кстати, можешь с NIST'а скачать тулзу для проверки рядов на случайность. Там есть сиды тестовые.

vasily_pupkin ★★★★★
()

В man rand утверждается, что младшие биты вредно использовать отдельно, ибо у них случайность хромает, так что rand()%2 следует заменить на rand()/(RAND_MAX/2).

anonymous
()

под виндой CryptGenRandom

anonymous
()

> .. генерировать достаточно случайные числа

1. можно применять любую хеш-функцию к 'не вполне' удовлетворительной последовательности. Можно в частности шифровать :)

> srand, rand()%2 мне выдает с глазу не особо случайный ряд

2. если нужна случайная последовательность бит, то можно брать все биты от результата rand() а не только последний.

p.s. была такая карикатура - ГСЧ выдаёт одни 0, чел. спрашивает - "разве это случайные числа?" ему отвечают - "никто не может знать, может просто так склалось"

MKuznetsov ★★★★★
()
Ответ на: комментарий от Stahl

fd сравнивай с -1, отрицательных дескрипторов я ещё не видел :).

true_admin ★★★★★
()

всем спасибо за внимание. пищи для размышлений много :)

Pi ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.