|
Как функцией rand() получить число от 0 до 2 ? |
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 33)
|
Jan 13 2008, 11:50
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Функция int rand(void) возвращает целое число в диапазоне [0, RAND_MAX]. Функция void srand(int seed) служит для задания начального значения случайной последовательности. Для Вашего случая слишком маловат диапазон, или Вы хотите результат с плавающей точкой? Пример лучше переписать так: Код #define RAND_MAX 2000 for (y=0;y<3;y++) { srand(5); // любое число не = 1 Current[y] = (float)rand() / 1000.0; // если это массив значений float }
|
|
|
|
|
Jan 13 2008, 11:57
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(IgorKossak @ Jan 13 2008, 14:50)  Функция int rand(void) возвращает целое число в диапазоне [0, RAND_MAX]. Функция void srand(int seed) служит для задания начального значения случайной последовательности. Для Вашего случая слишком маловат диапазон, или Вы хотите результат с плавающей точкой? Пример лучше переписать так: Код #define RAND_MAX 2000 for (y=0;y<3;y++) { srand(5); // любое число не = 1 Current[y] = (float)rand() / 1000.0; // если это массив значений float } ЭЭЭ! srand() надо вынести ЗА цикл. Иначе получите просто одинаковые значения при каждом вызове rand()!
|
|
|
|
|
Jan 13 2008, 11:59
|

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

|
Цитата(IgorKossak @ Jan 13 2008, 13:50)  Пример лучше переписать так: Код for (y=0;y<3;y++) { srand(5); // любое число не = 1 Current[y] = (float)rand() / 1000.0; // если это массив значений float } Ошибка. Это псевдослучайный генератор, который стабильно будет повторять последовательность при одинаковом исходном значении. Посему, как минимум, srand() вне цикла: Код srand(5); // любое число не = 1 for (y=0;y<3;y++) { ......... }
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 13 2008, 13:33
|

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

|
Цитата(IgorKossak @ Jan 13 2008, 13:50)  Функция int rand(void) возвращает целое число в диапазоне [0, RAND_MAX]. ... Пример лучше переписать так: Код #define RAND_MAX 2000 for (y=0;y<3;y++) { srand(5); // любое число не = 1 Current[y] = (float)rand() / 1000.0; // если это массив значений float } А-а-а!!! У-у-у!!!  Нет, ну я не могу сдержаться, чесслово. А сделать Код #define LONG_MAX 7 #define LONG_MIN -8 и таким образом ограничить диапазон значений long никто не пробовал? Рекомендую! А если вдруг я ещё не все комнаты смеха посетил и где-то есть компилятор, настолько не соответствующий стандарту, что переопределение RAND_MAX в пользовательском коде вот так просто влияет на поведение библиотечной rand() - адресок сбросьте, а! -=Женек=-, думаю, для светодиодов каких-то особых качеств генератора не нужно и этого хватит с головой (если вообще использовать библиотечный rand() ) Код #include <stdlib.h>
unsigned char led_rand() { unsigned char r; do { r = rand() & 0x03; } while( r == 3); // тута ошибочка была, исправлено return r; } srand() вызывать вообще не обязательно. Ну если хочется, чтобы каждый раз при включении не повторялась 1:1 последовательность (всё равно когда-то выйдет на цикл, но хоть чтобы не стартовало каждый раз с разного места) - то надо делать srand() с каким-то "внешне-случайным" аргументом - содержимым какого-то свободно-бегущего атймера в момент нажатия пользователем какой-то кнопки, ещё что-то такое найти.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jan 13 2008, 13:59
|

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

|
Цитата(ReAl @ Jan 13 2008, 15:33)  А-а-а!!! У-у-у!!!  Код r = rand() & 0x03; } Так просто не отделаетесь  - Автор хотел диапазон 0...2 а не 0...3 Цитата srand() вызывать вообще не обязательно. Ну хоть какой-то элемент случайности  ввиде однократного выбора при программировании вызов srand() c аргументом отличным от 1 вносит...
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 13 2008, 14:55
|

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

|
Цитата Так просто не отделаетесь - Автор хотел диапазон 0...2 а не 0...3 .... Цитата(ReAl @ Jan 13 2008, 15:33)  Код do { r = rand() & 0x03; } while( r != 3); Так там цикл, пока результат=3, повторять. Чето тема получилась веселейшая. На наших гуру и шаманов видимо торможение напало  - Старый Новый год, чтоли? Цитата Хороший генератор, как цвет автомобиля у Генри Форда Черт. И я торможу. Там конечно должно быть while(r==3) Все, на сегодня с форумом надо завязывать.
Сообщение отредактировал zltigo - Jan 13 2008, 14:56
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Jan 13 2008, 16:21
|

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

|
Цитата(-=Женек=- @ Jan 13 2008, 17:43)  Господа, ну конкретный результат кто-нибудь может выдать? Current[y] = rand() / (RAND_MAX / 3); Арифметика, пропорции, четвертый класс.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 13 2008, 17:09
|

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

|
Цитата(Сергей Борщ @ Jan 13 2008, 18:21)  Current[y] = rand() / (RAND_MAX / 3); Арифметика, пропорции, четвертый класс. Сергей! Ты, конечно, не поверишь!! но это правда!!! - твой ответ неверен!!!!  При значении rand() == RAND_MAX ты получишь число 3  Осталось чуть-чуть подправить, но на этом пути есть еще одна проблемка. Не наступи! Цитата(-=Женек=- @ Jan 13 2008, 18:34)  брр... а RAND_MAX тогда чему равен? Не принципиально, а где конкретное значение посмотреть я писал. Цитата(Kirill Trusov @ Jan 13 2008, 18:41)  1. для какого компилятора , винавр? Любого сишного. Это ANSI, однако. На счет остального пока помолчу, дабы интрига осталась....
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 13 2008, 17:35
|
Знающий
   
Группа: Свой
Сообщений: 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 чисел. Маленькая просьба, отвечать только тех, кто проверил это у себя на компе. С уважением.
|
|
|
|
|
Jan 13 2008, 17:47
|

Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
|
Jan 13 2008, 18:26
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
Знаете, за что я благодарен форуму? Пока дождешься пока кто-нибудь ответит, доходит до самого. Вот код, который у меня работает Цитата for (y=0;y<3;y++) Current[y]=(unsigned int)((rand()-2768)/10000);
|
|
|
|
|
Jan 13 2008, 18:45
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
Я прекрасно понимаю что делаю, это вы не понимаете мой код, с чего вы взяли, что я беру остаток от деления? Я беру случайное число, вычитаю из него 2768, чтобы результат был не выше 29999, делаю с ним (unsigned int), чтобы результат не был отрицательным. Далее делю на 10000 и беру результат, а не остаток от деления. В тоге получаю 0,1 или 2.
|
|
|
|
|
Jan 13 2008, 18:51
|

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

|
Цитата(-=Женек=- @ Jan 13 2008, 20:45)  Я беру случайное число, вычитаю из него 2768, чтобы результат был не выше 29999, делаю с ним (unsigned int), чтобы результат не был отрицательным. Далее делю на 10000 и беру результат Вот результат Вы себе и не представляете  . 1. результат зависит от MAX_RAND, который отнюдь не обязан бвть 0x7FFF 2. При подаче на вход случайной последовательности получите искажение исходного распределения вероятности. Цитата , а не остаток от деления. Я учился в школе, по этой причине я не мог говорить, что Вы берете остаток от деления, я говорил, что НАДО ПРОСТО ВЗЯТЬ ОСТАТОК ОТ ДЕЛЕНИЯ. Код Current[y] = rand() % 3;
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 13 2008, 19:02
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
И что? ну пусть будет 31232, делим на 3, получаем 232. Вот вам 5 чисел: 15325 10234 00323 23954 31222 ПРоделайте свой код с каждым из них в письменном виде здесь на форуме и выложите результат. Цитата 1. результат зависит от MAX_RAND, который отнюдь не обязан бвть 0x7FFF Кстати, MAX_RAND менял - не помогало.
|
|
|
|
|
Jan 13 2008, 19:14
|

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

|
Цитата(zltigo @ Jan 13 2008, 20:51)  НАДО ПРОСТО ВЗЯТЬ ОСТАТОК ОТ ДЕЛЕНИЯ. Верхняя математика мне давалась тяжело, поэтому вопрос - будет ли остаток иметь такое же распределение, как и исходное число? Интуитивно чувствую, что частное будет, а остаток? Цитата(zltigo @ Jan 13 2008, 19:09)  Сергей! Ты, конечно, не поверишь!! но это правда!!! - твой ответ неверен!!!!  При значении rand() == RAND_MAX ты получишь число 3  Ну ладно, подколол, подколол  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)
|
|
|
|
|
Jan 13 2008, 19:19
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 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.
Вроде нигде не промахнулся...
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Jan 13 2008, 19:29
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 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, но и этого достаточно.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jan 13 2008, 19:51
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 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
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Jan 13 2008, 20:29
|

Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
|
Jan 14 2008, 19:57
|
Участник

Группа: Новичок
Сообщений: 17
Регистрация: 2-02-07
Пользователь №: 24 993

|
Код int a = (new java.util.Random()).nextInt(3); Осталось Java для микроконтроллеров написать
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|