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 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.