реклама на сайте
подробности

 
 
> Как функцией rand() получить число от 0 до 2 ?
-=Женек=-
сообщение Jan 13 2008, 11:33
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131



Как функцией rand() получить число от 0 до 2 ?
Да и объясните про srand() я каждый раз в цикле вызываю srand(rand()); но на работу rand() это не оказывает влияния.

короче говоря у меня есть массив Current[3], его нужно заполнить числами от 0 до 2

for (y=0;y<3;y++)
{
srand(rand());
Current[y]= что здесь?

}
Go to the top of the page
 
+Quote Post
3 страниц V  < 1 2 3 >  
Start new topic
Ответов (15 - 29)
-=Женек=-
сообщение Jan 13 2008, 17:35
Сообщение #16


Знающий
****

Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131



Цитата
я конечно салага но 3 вопроса
1. для какого компилятора , винавр?


Салага, наверное, я, но уже было написано выше, что компилятор CodeVision


Цитата
unsigned char led_rand()
{
unsigned char r;
do {
r = rand() & 0x03;
} while( r == 3); // тута ошибочка была, исправлено
return r;
}



Возвращает всегда 0 (((

ПОЛЦАРСТВА за
РАБОЧИЙ лишенный всяких философских непонятных абстракций
пример для CodeVision генерирующий любоей из 0,1,2 чисел.

Маленькая просьба, отвечать только тех, кто проверил это у себя на компе.

С уважением.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 13 2008, 17:47
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(-=Женек=- @ Jan 13 2008, 19:35) *
Возвращает всегда 0 (((

Это невозможно, если только CodeVision компилятор "C" а не "языка похожего на C". Должен выдавать числа в требуемом диапазоне. Единственно, что вероятность нескольких нулей подряд отнюдь не мала, а повторяемость, как тут было уже трижды написано, 100%, поскольку rand() есть просто генератор ПСЕВДОСЛУЧАЙНОЙ последовательности однозначно задаваемой аргументом при вызове srand(). Про генерацию "случайных" , Вам ReAl рассказал.
Единственно, что максимально близкий к рабочему каноническому варианту описан в п.2 у Kirill Trusov.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
-=Женек=-
сообщение Jan 13 2008, 18:26
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131



Знаете, за что я благодарен форуму?
Пока дождешься пока кто-нибудь ответит, доходит до самого.
Вот код, который у меня работает
Цитата
for (y=0;y<3;y++) Current[y]=(unsigned int)((rand()-2768)/10000);
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 13 2008, 18:36
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(-=Женек=- @ Jan 13 2008, 20:26) *
Вот код, который у меня работает

Произвольные действия над псевдослучайным числом, естественно, могут выдавать разные цифири. Вы хоть поняли, что делаете?

Все очень просто делается. Просто берется остаток от деления на 3. Вот и все smile.gif.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
-=Женек=-
сообщение Jan 13 2008, 18:45
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131



Я прекрасно понимаю что делаю, это вы не понимаете мой код, с чего вы взяли, что я беру остаток от деления? Я беру случайное число, вычитаю из него 2768, чтобы результат был не выше 29999, делаю с ним (unsigned int), чтобы результат не был отрицательным. Далее делю на 10000 и беру результат, а не остаток от деления. В тоге получаю 0,1 или 2.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 13 2008, 18:51
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(-=Женек=- @ Jan 13 2008, 20:45) *
Я беру случайное число, вычитаю из него 2768, чтобы результат был не выше 29999, делаю с ним (unsigned int), чтобы результат не был отрицательным. Далее делю на 10000 и беру результат

Вот результат Вы себе и не представляете sad.gif.
1. результат зависит от MAX_RAND, который отнюдь не обязан бвть 0x7FFF
2. При подаче на вход случайной последовательности получите искажение исходного распределения вероятности.
Цитата
, а не остаток от деления.

Я учился в школе, по этой причине я не мог говорить, что Вы берете остаток от деления, я говорил, что НАДО ПРОСТО ВЗЯТЬ ОСТАТОК ОТ ДЕЛЕНИЯ.
Код
   Current[y] = rand() % 3;


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
-=Женек=-
сообщение Jan 13 2008, 19:02
Сообщение #22


Знающий
****

Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131



И что? ну пусть будет 31232, делим на 3, получаем 232.

Вот вам 5 чисел:

15325
10234
00323
23954
31222

ПРоделайте свой код с каждым из них в письменном виде здесь на форуме и выложите результат.


Цитата
1. результат зависит от MAX_RAND, который отнюдь не обязан бвть 0x7FFF


Кстати, MAX_RAND менял - не помогало.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jan 13 2008, 19:04
Сообщение #23


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
ПРоделайте свой код с каждым из них в письменном виде здесь на форуме и выложите результат.


1, 1, 2, 2, 1

А Вы это сделали? Не путайте операцию "/" (деление) с операцией "%" (остаток от деления)


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 13 2008, 19:14
Сообщение #24


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(zltigo @ Jan 13 2008, 20:51) *
НАДО ПРОСТО ВЗЯТЬ ОСТАТОК ОТ ДЕЛЕНИЯ.
Верхняя математика мне давалась тяжело, поэтому вопрос - будет ли остаток иметь такое же распределение, как и исходное число? Интуитивно чувствую, что частное будет, а остаток?

Цитата(zltigo @ Jan 13 2008, 19:09) *
Сергей! Ты, конечно, не поверишь!! но это правда!!! - твой ответ неверен!!!! sad.gif
При значении rand() == RAND_MAX ты получишь число 3 smile.gif
Ну ладно, подколол, подколол smile.gif Current[y] = rand() / ((RAND_MAX + 1) / 3). Ну и еще подумать об округлениях. Тогда ((RAND_MAX + 2) / 3).

Цитата(-=Женек=- @ Jan 13 2008, 20:45) *
делаю с ним (unsigned int), чтобы результат не был отрицательным. Далее делю на 10000 и беру результат
Посмотрите внимательнее свой код - вы преобразуете к (unsigned int) результат после деления, а не до.
Цитата(-=Женек=- @ Jan 13 2008, 21:02) *
Кстати, MAX_RAND менял - не помогало.
Библиотечный макрос называется RAND_MAX. ReAl вам пытался объяснить, что RAND_MAX менять не нужно - она задана вам "свыше" автором библиотеки. И как бы вы ее не меняли - код, скомпилированный в библиотеку об этом ничего не знает. Переопределяя RAND_MAX вы можете только сделать ваш код обработки (если он использует RAND_MAX) несовместимым с библиотечной функцией, ничего больше.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jan 13 2008, 19:19
Сообщение #25


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Другое дело, что деление сюда прикладывать как-то совсем не хочется. Так что я бы делал что-то типа

unsigned int i=(unsigned int)rand()/((RAND_MAX+1)/256);
i=i+i+i;
i>>=8;

В результате деление в первой строке (если RAND_MAX не совсем психозный) будет преобразовано к сдвигу (причем, специально каст к unsigned, чтобы знак не расширять) и даст результат 0..255, потом мы его умножим на 3 (сложением, чтобы компилятор не дай бог не позвал процедуру умножения) и разделим на 256 - получим результат от 0 до 2, с таким же распределением, как и rand.

Вроде нигде не промахнулся...


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jan 13 2008, 19:29
Сообщение #26


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Я дал рабочий пример (с учётом поправки, сначала по ошибке написал while(r != 3) а надо while( r == 3) ).
Как правило я проверяю код перед отправкой, но тут не проверял, так как был уверен в работоспособности (в случае применения вменяемого компилятора С и достаточно стандартной библиотекой).

Нужна проверка? "Их есть у меня"
CODE
#include <stdio.h>
#include <stdlib.h>

unsigned char rnd3(void)
{
unsigned char val;
do {
val = rand() & 0x03;
} while( val == 3);
return val;
}


unsigned char rnd3div(void)
{
return ((rand()-2768)/10000);
}

unsigned char rnd3mod(void)
{
return rand() % 3;
}


void test( char *header, unsigned char (*rndfunc)(void), int count)
{
int i, prev;
int gist[3] = {0};
int gist2[3][3] = { {0} };

printf("\n-------------------------------\n%s\nvalue table\n", header);

prev = rnd3();
for( i = 0; i < count; ++i) {
unsigned char r = rndfunc();
printf( (i & 0x1F) == 0 ? "\n%2d" : "%2d" , r );
++gist[r];
++gist2[prev][r];
prev = r;
}

printf("\n\n%s - frequency table\n", header);
for( i = 0; i < 3; ++i)
printf( "%d -> %3d\n", i, gist[i] );

printf("\n%s - prev/curent frequency table\n", header);
printf(" 0 1 2\n");

for( i = 0; i < 3; ++i)
printf( "%d%6d%6d%6d\n", i, gist2[i][0], gist2[i][1], gist2[i][2] );

}


int main(void)
{
test( "rand() & 0x03", rnd3, 1024);
test( "(rand() - 2768) / 10000", rnd3div, 1024);
test( "rand() % 3", rnd3mod, 1024);

return 0;
}


mingw32-gcc -O2 -s rnd3.c -o rnd3.exe
rnd3 >rnd3.txt

CODE

-------------------------------
rand() & 0x03
value table

2 0 1 0 2 2 2 0 1 1 1 1 2 0 0 2 1 0 2 1 0 2 2 2 1 0 2 2 1 1 0 1
1 0 0 2 1 1 1 1 2 0 2 2 0 2 0 2 0 0 2 1 2 1 2 2 2 1 1 0 1 0 2 0
0 2 0 0 0 2 1 2 2 2 1 1 1 2 0 2 1 2 1 2 1 1 0 0 2 1 1 1 1 0 2 2
1 0 2 0 2 2 1 0 2 2 1 1 1 1 1 1 2 1 0 2 2 2 2 1 0 0 2 2 0 1 0 1
2 2 0 2 0 0 1 0 0 0 1 2 1 2 2 0 0 0 1 0 1 2 1 1 2 1 0 0 1 0 2 0
0 0 1 1 2 1 1 2 0 0 2 2 0 0 2 1 1 2 1 1 0 2 2 0 2 2 1 2 0 0 2 2
0 0 2 2 2 1 1 2 0 0 1 2 2 1 1 0 0 1 0 0 2 1 1 0 1 1 2 1 2 1 0 2
1 1 0 0 1 2 1 1 0 1 0 0 1 2 1 1 0 1 0 2 1 0 1 1 1 2 1 1 1 0 2 1
0 2 2 2 1 0 2 1 1 1 0 0 0 1 1 0 1 2 2 2 1 0 0 2 1 1 2 1 2 0 0 1
0 2 2 1 1 2 1 2 2 0 2 1 2 2 1 1 2 2 0 2 2 0 1 2 1 2 1 1 2 0 0 1
2 0 1 2 1 0 0 1 1 0 1 1 1 0 2 2 2 0 0 0 1 2 2 2 1 0 0 1 2 0 2 0
1 0 2 2 2 2 2 1 0 2 0 0 0 0 2 2 1 2 0 2 0 1 2 2 1 1 2 1 1 0 0 2
2 0 1 1 1 0 0 2 0 2 2 1 0 2 0 0 0 2 1 0 1 2 2 1 1 0 2 0 1 0 1 0
1 1 2 0 0 1 0 1 0 0 0 0 2 1 0 0 2 1 2 1 1 1 1 0 2 1 0 1 0 1 1 1
1 1 0 0 1 2 0 2 2 0 1 1 0 0 2 2 2 1 1 1 2 2 2 1 2 2 1 1 2 1 2 0
1 0 1 2 0 1 0 1 1 2 2 1 0 2 0 0 1 0 1 0 2 2 1 0 0 1 0 0 1 2 1 1
2 1 1 2 0 0 2 0 1 0 1 1 0 0 1 1 0 1 1 1 0 1 2 1 1 1 0 0 1 0 2 0
0 2 2 2 0 1 2 2 1 0 0 2 1 0 2 0 2 1 2 2 0 0 0 1 1 0 2 2 1 2 1 1
0 1 0 1 0 2 2 1 0 0 0 2 1 0 1 1 0 0 1 1 1 1 0 2 0 0 1 2 2 0 2 2
1 2 0 0 0 2 1 2 1 1 0 0 1 2 0 2 2 1 1 1 0 0 0 2 1 2 0 0 0 2 2 1
1 0 1 2 0 1 1 0 0 1 2 2 0 0 0 2 2 2 1 1 1 2 2 2 2 2 1 1 0 0 0 2
1 2 2 0 0 0 1 1 1 0 0 0 2 2 2 1 0 0 1 2 1 1 0 2 1 2 0 2 1 2 0 1
1 0 0 1 1 2 1 2 2 1 2 1 2 0 1 1 1 1 1 2 0 0 1 2 0 0 2 2 1 2 0 2
0 1 2 2 1 0 1 0 0 1 1 0 1 2 0 0 2 0 1 2 1 1 0 1 0 1 2 2 1 1 2 0
0 1 0 0 1 1 2 0 0 2 2 1 0 0 2 1 2 1 0 1 2 1 0 1 1 2 2 0 2 2 1 0
0 2 2 1 0 0 2 1 0 0 2 1 0 0 0 2 2 2 0 0 1 2 2 2 2 2 0 2 1 2 2 2
0 1 1 2 2 2 2 0 0 2 0 0 2 0 2 0 1 2 1 0 0 2 1 1 2 1 0 0 0 2 0 1
2 2 2 2 2 0 1 2 1 0 2 2 1 0 1 2 1 0 1 1 2 2 1 1 2 1 0 1 2 1 0 2
0 1 1 1 0 1 0 2 0 0 1 1 0 1 0 2 0 2 0 0 1 0 2 1 1 1 1 1 0 2 1 0
2 1 2 1 0 1 1 1 0 0 2 0 2 2 2 2 2 0 2 0 2 0 2 0 2 0 1 2 1 1 1 2
2 2 1 0 0 0 0 2 0 0 2 0 2 2 1 2 2 0 0 0 0 2 1 2 0 0 2 2 0 0 2 0
2 1 0 2 1 1 2 1 0 0 0 0 2 1 0 0 1 0 1 2 1 1 1 2 0 2 1 0 2 1 1 1

rand() & 0x03 - frequency table
0 -> 336
1 -> 352
2 -> 336

rand() & 0x03 - prev/curent frequency table
0 1 2
0 115 102 119
1 125 120 107
2 96 130 110

-------------------------------
(rand() - 2768) / 10000
value table

1 1 2 1 2 2 2 0 1 2 0 1 0 1 0 0 0 2 1 1 0 0 2 2 0 0 0 0 2 0 0 0
0 2 1 0 0 0 0 1 0 1 0 1 2 0 0 0 1 2 1 2 0 2 2 1 1 1 1 0 2 0 0 0
0 1 2 0 2 0 2 0 0 1 0 0 1 2 0 2 0 2 1 0 0 0 1 0 0 0 0 2 2 1 2 0
1 1 2 0 1 2 2 2 2 1 0 2 0 1 1 1 2 0 1 0 1 0 0 0 0 2 2 0 1 0 2 0
1 2 1 2 1 1 1 1 2 2 0 0 1 0 1 1 2 1 0 1 0 1 2 0 0 1 0 0 2 2 0 0
1 1 2 1 0 1 0 1 2 0 1 2 1 1 1 2 0 0 0 0 0 1 1 0 0 1 0 0 2 1 2 0
0 1 0 0 1 2 0 2 0 2 1 0 0 1 0 1 2 2 0 1 2 2 0 0 2 2 1 0 1 0 1 0
0 2 0 0 0 0 0 0 0 0 0 0 1 2 2 1 2 0 1 1 2 0 2 0 0 2 2 1 2 0 0 0
2 2 1 2 0 2 1 0 2 0 0 0 1 1 1 0 2 0 0 2 1 2 0 0 1 1 1 2 2 0 1 2
0 2 1 0 0 0 0 0 0 2 1 2 0 1 2 2 2 2 0 0 0 2 0 2 0 2 0 0 1 2 0 1
1 0 1 1 2 2 2 1 2 1 0 0 0 2 2 0 0 0 0 0 2 0 1 0 2 1 2 0 1 2 1 1
2 0 0 2 2 0 2 0 2 0 0 0 1 1 1 0 0 0 0 1 0 0 2 1 0 2 2 0 0 2 1 0
0 1 2 1 0 2 1 0 1 2 2 1 1 2 1 0 2 1 0 1 0 0 1 2 0 2 2 1 0 1 1 0
1 1 1 2 0 0 0 0 0 0 1 2 1 0 1 2 2 0 2 0 0 1 0 2 1 0 0 0 2 1 0 0
1 2 1 0 1 2 0 1 1 0 0 1 0 0 1 2 1 0 1 1 1 1 2 0 1 0 0 0 0 1 2 1
1 1 1 1 0 2 0 2 1 2 1 2 1 0 2 2 0 2 0 0 2 2 0 1 0 0 2 1 0 0 1 0
0 0 1 2 1 1 0 0 2 0 0 0 0 0 2 0 0 1 2 1 0 2 0 2 0 2 1 0 2 0 1 2
1 1 0 1 1 0 1 2 0 0 1 2 0 2 2 2 0 1 1 0 0 0 1 0 1 1 2 2 2 1 0 0
0 2 2 1 0 2 1 0 1 2 0 2 0 1 1 0 2 1 1 0 1 2 0 1 0 0 2 2 2 2 1 2
2 1 2 2 0 2 0 1 1 2 2 2 0 1 1 1 1 2 1 0 1 0 2 0 0 2 0 1 0 1 1 0
1 0 0 1 2 2 1 1 0 2 2 0 2 1 1 2 1 0 0 1 2 1 0 1 1 2 2 2 0 0 0 1
1 0 0 0 2 2 0 0 1 2 2 2 0 1 1 1 2 0 2 2 1 2 1 0 2 1 0 0 1 2 1 2
1 2 1 2 0 2 2 2 2 0 0 0 0 2 2 0 0 2 1 0 2 2 1 0 1 1 2 2 2 0 1 2
1 0 1 1 2 1 1 0 0 0 0 1 0 1 2 0 2 1 2 0 0 1 2 2 0 0 1 2 0 1 0 1
0 2 2 2 1 0 0 2 1 1 2 2 2 2 1 1 2 2 0 2 0 0 0 2 2 1 0 0 0 1 2 0
0 1 2 1 0 2 2 1 0 2 1 1 0 2 2 2 1 0 1 2 1 1 0 1 0 2 0 2 2 1 0 1
1 2 2 0 2 1 2 2 1 0 0 0 2 0 0 0 2 2 0 0 0 2 0 2 2 0 1 0 0 0 2 2
0 0 2 2 1 1 0 0 0 2 0 0 0 0 1 0 2 1 1 2 1 2 1 0 0 0 2 2 1 0 1 0
1 0 1 0 1 1 2 2 1 0 2 2 0 0 1 0 2 1 2 1 2 1 2 0 2 2 0 0 0 2 2 1
0 0 0 1 1 2 2 1 2 1 2 0 0 0 1 0 0 2 2 2 1 1 2 0 2 0 1 0 1 0 0 2
1 2 2 1 0 1 1 2 2 2 1 0 0 1 2 1 1 1 0 2 0 2 0 2 0 1 0 0 0 0 0 2
1 0 2 1 1 1 2 1 1 1 0 0 2 2 1 2 2 2 2 0 1 1 2 2 2 1 1 1 2 2 1 0

(rand() - 2768) / 10000 - frequency table
0 -> 402
1 -> 309
2 -> 313

(rand() - 2768) / 10000 - prev/curent frequency table
0 1 2
0 168 123 110
1 121 80 109
2 113 106 94

-------------------------------
rand() % 3
value table

2 0 2 0 1 1 1 2 1 2 0 0 2 1 2 2 2 1 1 0 1 0 1 0 1 2 0 1 0 0 0 1
2 2 2 1 1 1 1 0 0 0 1 1 2 2 2 2 1 1 0 0 0 2 2 0 2 0 2 0 2 1 0 1
2 1 0 1 1 0 1 2 0 0 2 0 2 0 0 2 2 2 2 1 2 2 0 1 1 1 0 2 2 0 2 2
2 0 0 1 1 0 1 0 1 2 0 1 2 2 2 0 0 2 1 0 1 1 2 1 0 1 2 0 1 1 2 1
0 0 2 0 2 1 2 1 2 2 0 1 0 0 0 0 0 0 0 1 2 1 0 1 1 2 2 2 0 2 0 2
1 1 0 1 2 1 0 1 1 0 1 2 1 1 0 2 0 1 1 0 0 2 0 2 1 1 2 1 1 1 1 0
1 0 1 0 0 2 1 1 1 2 2 0 2 1 1 1 0 0 2 2 0 1 2 1 0 2 1 0 1 1 0 1
2 0 2 0 2 2 1 0 0 2 1 0 0 1 0 0 1 2 0 1 1 1 0 2 1 1 1 2 2 0 1 0
0 1 2 0 1 2 1 1 2 2 1 1 0 2 1 1 2 1 0 0 2 1 1 2 2 2 2 0 1 0 2 1
0 1 1 2 0 1 1 1 1 2 2 1 1 2 2 1 2 1 0 2 0 2 1 0 1 2 0 2 2 0 0 1
0 1 2 2 1 1 0 2 0 1 1 1 2 2 0 0 1 1 0 0 2 0 1 2 1 2 1 0 2 0 1 0
2 0 0 0 0 1 2 1 1 1 0 1 2 2 0 2 1 2 0 2 1 2 0 2 2 1 0 0 2 2 2 2
1 1 0 0 2 1 1 1 1 0 0 2 0 2 0 1 1 1 2 1 0 2 0 1 2 0 1 0 1 0 1 2
2 0 2 0 1 0 0 1 2 1 1 0 1 0 1 1 2 1 0 1 0 1 0 1 2 2 1 2 2 2 1 0
0 1 0 1 1 2 1 0 2 2 2 2 0 0 0 1 2 0 1 0 0 0 1 2 2 0 1 1 1 1 0 2
0 0 0 2 2 0 0 1 2 0 2 0 0 1 1 2 2 1 0 0 2 0 0 2 2 1 2 2 0 2 2 2
1 0 1 2 1 0 0 1 2 0 0 1 0 1 1 0 2 0 2 1 2 1 1 2 2 2 0 2 1 1 1 1
2 2 1 0 2 2 0 0 1 2 2 0 1 0 1 0 2 1 2 0 2 1 0 2 2 1 1 0 2 2 0 1
1 0 1 0 0 0 0 1 0 0 1 1 2 1 0 2 2 2 1 2 1 0 0 0 1 2 2 0 0 2 1 1
2 2 0 0 1 0 1 2 2 0 2 0 0 0 2 1 1 2 2 2 1 2 0 0 0 2 2 2 1 0 2 2
0 2 1 0 0 2 0 2 0 0 0 1 1 2 0 1 0 1 0 0 2 1 0 0 0 2 1 1 1 0 0 1
2 0 2 1 2 0 1 2 1 1 2 1 1 2 1 2 2 1 0 2 1 0 1 1 1 0 1 0 0 0 1 1
0 2 2 0 2 1 0 1 0 2 1 0 2 2 0 2 1 0 2 2 1 2 2 2 1 2 1 1 0 0 2 1
2 0 2 1 0 2 2 1 0 2 0 2 0 1 2 0 0 1 2 0 1 2 0 1 1 2 0 0 0 0 2 0
1 0 1 1 0 1 1 1 2 2 2 2 2 1 1 0 1 2 2 2 0 0 1 0 0 0 2 0 2 2 2 1
0 1 0 2 0 1 2 1 1 2 2 0 0 1 2 0 2 1 0 0 0 0 1 1 0 2 2 0 2 0 2 0
2 1 0 0 1 0 0 1 0 1 2 0 0 0 2 2 0 0 0 2 1 2 0 0 1 1 0 2 2 2 0 0
0 0 0 0 1 2 1 0 0 0 0 2 2 1 1 2 1 2 1 2 2 1 2 1 2 2 1 1 2 2 1 0
1 1 0 0 2 0 2 2 0 1 1 2 2 0 2 0 2 0 1 0 1 0 1 2 2 1 1 2 1 0 0 0
2 2 2 2 0 1 0 1 0 2 2 0 1 1 1 2 2 1 0 0 1 0 0 1 2 1 0 1 0 0 0 0
2 1 0 1 1 2 0 1 0 2 2 2 0 2 0 0 2 2 2 2 0 2 1 0 1 1 1 1 0 1 1 2
0 2 2 1 1 2 0 2 1 1 2 1 2 0 0 1 1 0 1 1 1 0 2 1 2 1 2 1 2 1 0 0

rand() % 3 - frequency table
0 -> 348
1 -> 344
2 -> 332

rand() % 3 - prev/curent frequency table
0 1 2
0 109 126 112
1 128 104 112
2 111 114 108


И, чтобы легче сравнивать, только распределения.
Код
-------------------------------
rand() & 0x03 - frequency table
0 -> 336
1 -> 352
2 -> 336

rand() & 0x03 - prev/curent frequency table
      0     1     2
0   115   102   119
1   125   120   107
2    96   130   110

-------------------------------
(rand() - 2768) / 10000 - frequency table
0 -> 402
1 -> 309
2 -> 313

(rand() - 2768) / 10000 - prev/curent frequency table
      0     1     2
0   168   123   110
1   121    80   109
2   113   106    94

-------------------------------
rand() % 3 - frequency table
0 -> 348
1 -> 344
2 -> 332

rand() % 3 - prev/curent frequency table
      0     1     2
0   109   126   112
1   128   104   112
2   111   114   108

Как видим, мой примитив с выдёргиванием двух младших битов и отбрасыванием троек даёт распределения немного хуже, чем "%3", но лучше, чем "/10000".
Зато обходится без деления.

Вообще говоря, гонять нужно было с srand(1) перед каждым тестом и (RAND_MAX+1) проб, а не 1024, но и этого достаточно.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 13 2008, 19:31
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Сергей Борщ @ Jan 13 2008, 21:14) *
Ну ладно, подколол, подколол smile.gif Current[y] = rand() / ((RAND_MAX + 1) / 3).

Подставился!
А RAND_MAX+1 это сколько? 0 при unsigned или вообще отрицательное число при signed?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jan 13 2008, 19:51
Сообщение #28


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
Вроде нигде не промахнулся...


Таки немного промахнулся. Вообщем, примерно вот так надо делать (правда, только IAR под рукой, он конечно, зажыгает)
Код
    165          char rrr(void)
   \                     rrr:
    166          {
    167            unsigned int i=((unsigned int)rand()/(((unsigned int)RAND_MAX+1)/256))&255;
   \   00000000   ........           CALL    rand
   \   00000004   0F00               LSL     R16
   \   00000006   2F01               MOV     R16, R17
   \   00000008   1F00               ROL     R16
    168            i=i+i+i;
    169            i>>=8;
    170            return (char)i;
   \   0000000A   E023               LDI     R18, 3
   \   0000000C   9F20               MUL     R18, R16
   \   0000000E   2D01               MOV     R16, R1
   \   00000010   9508               RET


Без аппаратного умножения тоже все в порядке
Код
      4            unsigned int i=((unsigned int)rand()/(((unsigned int)RAND_MAX+1)/256))&255;
   \   00000000   ....               RCALL   rand
   \   00000002   0F00               LSL     R16
   \   00000004   2F01               MOV     R16, R17
   \   00000006   1F00               ROL     R16
   \   00000008   E010               LDI     R17, 0
      5            i=i+i+i;
      6            i>>=8;
      7            return (char)i;
   \   0000000A   2F20               MOV     R18, R16
   \   0000000C   E030               LDI     R19, 0
   \   0000000E   0F00               LSL     R16
   \   00000010   1F11               ROL     R17
   \   00000012   0F02               ADD     R16, R18
   \   00000014   1F13               ADC     R17, R19
   \   00000016   2F01               MOV     R16, R17
   \   00000018   9508               RET


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jan 13 2008, 19:55
Сообщение #29


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(zltigo @ Jan 13 2008, 21:31) *
Подставился!
А RAND_MAX+1 это сколько? 0 при unsigned или вообще отрицательное число при signed?

По стандарту rand() имеет тип int и возвращает значения в диапазоне [0, RAND_MAX], так что RAND_MAX <= INT_MAX и (RAND_MAX+1) вполне влазит в unsigned int.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 13 2008, 20:29
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(ReAl @ Jan 13 2008, 21:55) *
вполне влазит в unsigned int.

Влазит, но тогда будет надо корректно явно производить операции с unsigned.
Например, что будет напечатано:
Код
#define SOME 0x7FFFFFFF
int z = SOME;
printf( "Result1=%i\n", z/((SOME+1)/3) );
printf( "Result2=%u \n", z/((SOME+1)/3) );
printf( "Result3=%i\n", ((unsigned int)z)/((SOME+1)/3) );

Это я и имел ввиду,когда писал Сергею
Цитата
Не наступи!


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th July 2025 - 19:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.01547 секунд с 7
ELECTRONIX ©2004-2016