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

 
 
> Как функцией 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
Ответов (1 - 33)
IgorKossak
сообщение Jan 13 2008, 11:50
Сообщение #2


Шаман
******

Группа: Модераторы
Сообщений: 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
}
Go to the top of the page
 
+Quote Post
Petka
сообщение Jan 13 2008, 11:57
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 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()!
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 13 2008, 11:59
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
-=Женек=-
сообщение Jan 13 2008, 12:21
Сообщение #5


Знающий
****

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



мне не нужна плавающа точка.
Ваш пример не работает. Не могу к сожалению проверить, что он выдает, от числа получаемого фоункцией зависит номер зажигаемого светодиода - в моем случае не горит ничего.
Пишу в CodeVision
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 13 2008, 12:52
Сообщение #6


Гуру
******

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



Цитата(-=Женек=- @ Jan 13 2008, 14:21) *
от числа получаемого фоункцией зависит номер зажигаемого светодиода

1. Число лежит в диапазоне от 0 до RAND_MAX, кое обычно (посмотрите в stdlib.h) не менее 16bit, посему нужно нормализировать до диапазона 0...2 перед употреблением.
2. Уже писал - самое главное rand() НЕ ГЕНЕРИТ СЛУЧАЙНЫЕ ПОСЛЕДОВАТЕЛЬНОСТИ, посему получить четыре случайных числа при каждом запуске не сможете.


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


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

Группа: Свой
Сообщений: 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
}

А-а-а!!! У-у-у!!! lol.gif
Нет, ну я не могу сдержаться, чесслово.
А сделать
Код
#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() с каким-то "внешне-случайным" аргументом - содержимым какого-то свободно-бегущего атймера в момент нажатия пользователем какой-то кнопки, ещё что-то такое найти.


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


Гуру
******

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



Цитата(ReAl @ Jan 13 2008, 15:33) *
А-а-а!!! У-у-у!!! lol.gif
Код
        r = rand() & 0x03;
}

Так просто не отделаетесь smile.gif - Автор хотел диапазон 0...2 а не 0...3
Цитата
srand() вызывать вообще не обязательно.

Ну хоть какой-то элемент случайности smile.gif ввиде однократного выбора при программировании вызов srand() c аргументом отличным от 1 вносит...


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


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

Группа: Модераторы
Сообщений: 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, повторять. Чето тема получилась веселейшая. На наших гуру и шаманов видимо торможение напало smile.gif - Старый Новый год, чтоли?

Цитата
Хороший генератор, как цвет автомобиля у Генри Форда


Черт. И я торможу. Там конечно должно быть while(r==3)

Все, на сегодня с форумом надо завязывать. smile.gif

Сообщение отредактировал zltigo - Jan 13 2008, 14:56


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


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

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



Да, конечно, while( r == 3), это я глюкнул - не успокоился ещё, а уже писать начал - и сам народ повеселил biggrin.gif


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
-=Женек=-
сообщение Jan 13 2008, 15:43
Сообщение #11


Знающий
****

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



Господа, ну конкретный результат кто-нибудь может выдать?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 13 2008, 16:21
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
-=Женек=-
сообщение Jan 13 2008, 16:34
Сообщение #13


Знающий
****

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



брр... а RAND_MAX тогда чему равен? И к чему эти деления,
если я изначально пропишу его как 3?
Go to the top of the page
 
+Quote Post
Kirill Trusov
сообщение Jan 13 2008, 16:41
Сообщение #14


Частый гость
**

Группа: Свой
Сообщений: 90
Регистрация: 17-08-07
Пользователь №: 29 867



я конечно салага но 3 вопроса
1. для какого компилятора , винавр?
2. разве не надо было брать rand()%2 брать целое от деления, вроде на си так в прогах писал когда надо было псевдослучаееноость

3. а вообще есть такая библиотека для авр, т.е на основании чаво она генерирует числа? не проще ли записать какойто набор чисел случаенных и по ним ходить по кругу, всяко ранд тоже псевдослучаенные дает
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 13 2008, 17:09
Сообщение #15


Гуру
******

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



Цитата(Сергей Борщ @ Jan 13 2008, 18:21) *
Current[y] = rand() / (RAND_MAX / 3);
Арифметика, пропорции, четвертый класс.

Сергей! Ты, конечно, не поверишь!! но это правда!!! - твой ответ неверен!!!! sad.gif
При значении rand() == RAND_MAX ты получишь число 3 smile.gif
Осталось чуть-чуть подправить, но на этом пути есть еще одна проблемка. Не наступи!

Цитата(-=Женек=- @ Jan 13 2008, 18:34) *
брр... а RAND_MAX тогда чему равен?

Не принципиально, а где конкретное значение посмотреть я писал.


Цитата(Kirill Trusov @ Jan 13 2008, 18:41) *
1. для какого компилятора , винавр?

Любого сишного. Это ANSI, однако.
На счет остального пока помолчу, дабы интрига осталась....


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
-=Женек=-
сообщение 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
mdmitry
сообщение Jan 13 2008, 21:44
Сообщение #31


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Вопрос в дискуссию: кто-нибудь из авторов вариантов проверял плотность распределения (гистограмму) и корреляционную функцию результата? Там все хорошо со случайностью?


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 13 2008, 21:49
Сообщение #32


Гуру
******

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



Цитата(mdmitry @ Jan 13 2008, 23:44) *
Там все хорошо...

С этим и исходной последовательностью как попало будет, ибо требования к генератору ненормированы абсолютно. Ну а легкие искажения будут, как минимум обусловленные тем, что всесь диапазон генерации ровнехонько на три не делится.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Elegorod
сообщение Jan 14 2008, 19:57
Сообщение #33


Участник
*

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



Код
int a = (new java.util.Random()).nextInt(3);

Осталось Java для микроконтроллеров написать smile.gif
Go to the top of the page
 
+Quote Post
Kirill Trusov
сообщение Jan 15 2008, 19:52
Сообщение #34


Частый гость
**

Группа: Свой
Сообщений: 90
Регистрация: 17-08-07
Пользователь №: 29 867



Цитата(mdmitry @ Jan 13 2008, 23:44) *
Вопрос в дискуссию: кто-нибудь из авторов вариантов проверял плотность распределения (гистограмму) и корреляционную функцию результата? Там все хорошо со случайностью?


остаток от деления дает хорошее распределение , я делал на си в винде , по 10 000 на каждый, от 0 до 9 , распеделение равномерно, за исключением , но вполне yeah.gif
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 Текстовая версия Сейчас: 20th July 2025 - 18:08
Рейтинг@Mail.ru


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