#include <time.h>
......
srand( (unsigned)time( NULL ) );
x = rand()%8
Случайные числа С++
подскажите как обойти проблему того что rand()%8 выдаёт одни и те же числа
Код:
Цитата: Increaser
Код:
#include <time.h>
......
srand( (unsigned)time( NULL ) );
x = rand()%8
......
srand( (unsigned)time( NULL ) );
x = rand()%8
Я бы не рекомдовал использовать такой алгоритм ГСЧ, т.к. его довольно легко предугадать. Как говорил товарищь Z0MBiE: "генерация случайных чисел - слишком важный вопрос, чтобы оставлять его на волю случая."
Вот его варианты:
Цитата:
Улучшенный быстрый 32-битный генератор псевдослучайных чисел:
randseed dd ?
randcount db ?
randomize: pusha
call GetTickCount ; KERNEL32.GetTickCount
add randseed, eax
mov randcount, al
popa
retn
process_randseed:
mov eax, randseed
imul eax, 214013
add eax, 2531011
mov randseed, eax
dec randcount
jz randomize
retn
; вход: ECX=range
; выход: EAX=0..ECX-1
get_rnd_number: push ecx
push edx
call process_randseed
cmp ecx, 65536 ; необходимо
jb __mul ; только
__div: xor edx, edx ; если
div ecx ; ECX
xchg edx, eax ; бывает
jmp __exit ; >= 65536
__mul: shr eax, 16
imul eax, ecx
shr eax, 16
__exit: pop edx
pop ecx
retn
get_rnd_byte: call process_randseed
shr eax, 24
retn
get_rnd_dword: push ecx
call get_rnd_byte
shl eax, 24
xchg ecx, eax
call get_rnd_byte
shl eax, 16
or ecx, eax
call get_rnd_byte
mov ch, al
call get_rnd_byte
or eax, ecx
pop ecx
retn
randseed dd ?
randcount db ?
randomize: pusha
call GetTickCount ; KERNEL32.GetTickCount
add randseed, eax
mov randcount, al
popa
retn
process_randseed:
mov eax, randseed
imul eax, 214013
add eax, 2531011
mov randseed, eax
dec randcount
jz randomize
retn
; вход: ECX=range
; выход: EAX=0..ECX-1
get_rnd_number: push ecx
push edx
call process_randseed
cmp ecx, 65536 ; необходимо
jb __mul ; только
__div: xor edx, edx ; если
div ecx ; ECX
xchg edx, eax ; бывает
jmp __exit ; >= 65536
__mul: shr eax, 16
imul eax, ecx
shr eax, 16
__exit: pop edx
pop ecx
retn
get_rnd_byte: call process_randseed
shr eax, 24
retn
get_rnd_dword: push ecx
call get_rnd_byte
shl eax, 24
xchg ecx, eax
call get_rnd_byte
shl eax, 16
or ecx, eax
call get_rnd_byte
mov ch, al
call get_rnd_byte
or eax, ecx
pop ecx
retn
Цитата:
; input: RANGE - on the stack
; output: eax=[0..RANGE-1], ZF=0 if EAX==0
rnd: mov eax, randseed
imul eax, 214013
add eax, 2531011
mov randseed, eax
shr eax, 16
imul eax, [esp+4]
shr eax, 16
ret 4
randomize: pusha
call GetTickCount
xor randseed, eax
popa
ret
Цитата:
пример генерации буфера из случайных чисел, с использованием маздайных средств:
HCRYPTPROV hProv;
if (CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) != 0)
return -1;
BYTE* buf = new BYTE[ 65536 ];
CryptGenRandom(hProv, 65536, buf);
CryptReleaseContext(hProv, 0);
и т.д. и т.п.
Вы всегда используете С++ код перенасыщенный ассемблерными вставками?
Если честно - то выглядит уродски.
Цитата: Jail
Если честно - то выглядит уродски.
Самое главное - алгоритм генерирования совсем неочевиден.
А если нужно числа от 1 до 9 включительно? Какой примерно код нужно писать (с использованием rand() ). Например a=1; b=9;
Если это нужно для прикладной задачи, а я примерно на 99,99% уверен, что это то, чем вы занимаетесь, то достаточно стандартного ГПСЧ, берете стандартный или улучшенный рандом (из нормальной библиотеки, нормально реализованный и документированный, а не тот код, который тут привели выше как образец), и юзаете.
Если вам нужны истинно случайные числа (или псевдослучайные, приближенные к таковым) -- сначала обоснуйте, зачем. Потому что алгоритм истинно случайных чисел, вообще говоря, оксюморон.
Цитата: Mr. Stalker
А если нужно числа от 1 до 9 включительно? Какой примерно код нужно писать (с использованием rand() ). Например a=1; b=9;
Например, так:
Код:
unsigned int rnd()
{
seed^=0xDEADC0DE;
seed=(seed >> 16) | (seed << 16);
seed-=GetTickCount();
seed*=0xE9192939;
return (seed % 9 + 1);
}
{
seed^=0xDEADC0DE;
seed=(seed >> 16) | (seed << 16);
seed-=GetTickCount();
seed*=0xE9192939;
return (seed % 9 + 1);
}
Цитата: machgun
Например, так:
Код:
unsigned int rnd()
{
seed^=0xDEADC0DE;
seed=(seed >> 16) | (seed << 16);
seed-=GetTickCount();
seed*=0xE9192939;
return (seed % 9 + 1);
}
{
seed^=0xDEADC0DE;
seed=(seed >> 16) | (seed << 16);
seed-=GetTickCount();
seed*=0xE9192939;
return (seed % 9 + 1);
}
Я все понимаю, и твой код на самом деле неплохо генерит псевдослучайные числа, но все же автор-то то просил с использованием стандартных функций по работе с псевдослучайными числами.
Чтобы сгенерить, не вникая в тонкости их генерации.
Цитата: Mr. Stalker
А если нужно числа от 1 до 9 включительно? Какой примерно код нужно писать (с использованием rand() ). Например a=1; b=9;
Думать мы уже разучились, ага?
Код:
int range_rand(int a, int b) {
int range = b - a + 1;
int d = rand() % range;
return a + d;
}
int range = b - a + 1;
int d = rand() % range;
return a + d;
}
З.Ы. Zorkus, не пинай за медвежью услугу.
пример использования уже был приведен, но обратимся к первоситочнику:
http://www.cplusplus.com/reference/clibrary/cstdlib/rand.html
только srand выполняйте 1 раз при старте. а потом только щелкайте rand и всё!