Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.01.14;
Скачать: CL | DM;

Вниз

Траблка с Radnomiza   Найти похожие ветки 

 
Windows ©   (2006-12-24 21:12) [0]

Здравствуйте уважаемые...
ничего не понимаю...
 function CaseLetter: string;
   var
     i: integer;
 Begin
   Randomize;
   i := random(25);
   case i of
     0: Result := "a";   9: Result := "j";  18: Result := "s";
     1: Result := "b";  10: Result := "k";  19: Result := "t";
     2: Result := "c";  11: Result := "l";  20: Result := "u";
     3: Result := "d";  12: Result := "m";  21: Result := "v";
     4: Result := "e";  13: Result := "n";  22: Result := "w";
     5: Result := "f";  14: Result := "o";  23: Result := "x";
     6: Result := "g";  15: Result := "p";  24: Result := "y";
     7: Result := "h";  16: Result := "q";  25: Result := "z";
     8: Result := "i";  17: Result := "r";
   end;
 End;

если вызвать функцию допустим три раз подряд, то всегда одинаковый символ возвращается...


 
Anatoly Podgoretsky ©   (2006-12-24 21:14) [1]

> Windows  (24.12.2006 21:12:00)  [0]

Randomize; вынеси из функции


 
Eraser ©   (2006-12-24 21:15) [2]

> [0] Windows ©   (24.12.06 21:12)

справку читать будем?
Do not combine the call to Randomize in a loop with calls to the Random function. Typically, Randomize is called only once, before all calls to Random.


 
Loginov Dmitry ©   (2006-12-25 00:10) [3]

> если вызвать функцию допустим три раз подряд, то всегда
> одинаковый символ возвращается


нагло жжешь!


 
Windows ©   (2006-12-25 00:57) [4]

В том-то и дело, что ничего не работает никак...
пишу к примеру так
randomize;
a:=CaseLetter;
randomize;
b:=CaseLetter;
randomize;
c:=CaseLetter;
и всегда одно и то же!


 
Германн ©   (2006-12-25 01:04) [5]


> Windows ©   (25.12.06 00:57) [4]
>
> В том-то и дело, что ничего не работает никак...
> пишу к примеру так
> randomize;
> a:=CaseLetter;
> randomize;
> b:=CaseLetter;
> randomize;
> c:=CaseLetter;
> и всегда одно и то же!

см. [2]
...
> before all calls to Random
...


 
Kostafey ©   (2006-12-25 01:15) [6]

> [4] Windows ©   (25.12.06 00:57)

Гм. попробуй рассматривать randomize как инициализатор последовательности случайных чисел например:

randomize;
a:=CaseLetter;
b:=CaseLetter;
c:=CaseLetter;


 
Kostafey ©   (2006-12-25 01:19) [7]


...
> Begin
>   Randomize; - эту строку удалить
>   i := random(25);

...


 
ors_archangel ©   (2006-12-25 01:54) [8]


> Windows ©   (24.12.06 21:12) 

Randomize устанавливает RandSeed в зависимости от текущего времени, поэтому если ты перед Random (наприер, в цикле) вызывешь Randomize, то получаешь как раз совсем не Random, потому что RandSeed постоянно "сбрасывается"


 
Германн ©   (2006-12-25 02:39) [9]


> ors_archangel ©   (25.12.06 01:54) [8]
>
>
> > Windows ©   (24.12.06 21:12)
>
> Randomize устанавливает RandSeed в зависимости от текущего
> времени, поэтому если ты перед Random (наприер, в цикле)
> вызывешь Randomize, то получаешь как раз совсем не Random,
>  потому что RandSeed постоянно "сбрасывается"
>

Не знаю почему, но у меня сей пост вызывает раздражение. Он-то где-то как-то правильный, но для "Начинающих" слишком неопределённый. Имхо.


 
ors_archangel ©   (2006-12-25 04:14) [10]


> Германн ©   (25.12.06 02:39) [9]

Наверно, ты прав. Исправлюсь:
Если конкретней, то

procedure Randomize;
{$IFDEF LINUX}
begin
 RandSeed := _time(nil);
end;
{$ENDIF}
{$IFDEF MSWINDOWS}
var
 Counter: Int64;
begin
 if QueryPerformanceCounter(Counter) then
   RandSeed := Counter
 else
   RandSeed := GetTickCount;
end;
{$ENDIF}

- не знаю, как QueryPerfomanceCounter, но GetTickCount меняется только раз в миллисикунду, т.е. 1000 раз/сек, получаем что если проц = 1 GHz, то значение RandSeed не будет меняться (т.к. будет инициироваться после Randomazа одним и тем же значением) примерно 1 000 0000 / колво_тактов_на_итерацию_цикла (которое в данном случа не слишком большое), а так как Random - это что-то ворде

function Random: Extended;
const two2neg32: double = ((1.0/$10000) / $10000);  // 2^-32
asm
{       FUNCTION _RandExt: Extended;    }
       PUSH    EBX
       XOR     EBX, EBX
       IMUL    EDX,[EBX].RandSeed,08088405H
       INC     EDX
       MOV     [EBX].RandSeed,EDX
       FLD     [EBX].two2neg32
       PUSH    0
       PUSH    EDX
       FILD    qword ptr [ESP]
       ADD     ESP,8
       FMULP   ST(1), ST(0)
       POP     EBX
end;

т.е. мы умножаем RandSeed, затем добавляем к нему 1, сохраняем его новое значение, затем умножаем его ещё на константу… т.е. Random - это реккурентная функция, но начальный аргумент = RandSeed (который является глобальной переменной) и когда мы "сбрасываем" RandSeed (вызываем Randomize через очень малые промежутки времени, например в цикле с малым телом), то и Random получаем одинаковый, - даже хуже, мы получаем одинаковые последовательности Random на всю итерацию цикла, т.к. эти последовательности зависят только от начального значения RandSeed


 
Loginov Dmitry ©   (2006-12-25 07:57) [11]

Однако:


procedure TForm1.Button1Click(Sender: TObject);
var
 List: TStringList;
 I: Integer;
begin
 List := TStringList.Create;
 for I := 1 to 30 do
 begin
   Randomize;
   List.Add(IntToStr(Random(1000)));
 end;

 ShowMessage(List.Text);

 List.Free;
end;


В полученном списке числа далеко не одни и те же.


 
MBo ©   (2006-12-25 08:44) [12]

>В полученном списке числа далеко не одни и те же.
Потому что ты вызываешь нажатием на кнопку, и проходит достаточно времени. А если сделаешь отдельную процедуру и несколько раз подряд ее вызовешь программно, то с большой долей верочтности будут повторы


 
Windows ©   (2006-12-25 13:42) [13]

А вот теперь не знаю как понимать, я ничего в коде не менял, а сейчас вдруг заработало... Почему такое может быть!?


 
Anatoly Podgoretsky ©   (2006-12-25 14:04) [14]

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


 
Windows ©   (2006-12-25 14:37) [15]

не, второй код...
вот когда я вчера так делал, он мне всегда возвращал одно и то же...
а сегодня уже разные...


 
Германн ©   (2006-12-25 14:42) [16]


> Windows ©   (25.12.06 14:37) [15]
>
> не, второй код...
> вот когда я вчера так делал, он мне всегда возвращал одно
> и то же...
> а сегодня уже разные...
>

Вчера было восресенье. Нерабочий день :-)


 
Loginov Dmitry ©   (2006-12-25 15:08) [17]

> Потому что ты вызываешь нажатием на кнопку, и проходит достаточно
> времени


Это анализ кода или гадание?


 
MBo ©   (2006-12-25 15:41) [18]

>Loginov Dmitry ©   (25.12.06 15:08) [17]
>Это анализ кода или гадание?

навеяно вот этим:
procedure TForm1.Button1Click



Страницы: 1 вся ветка

Текущий архив: 2007.01.14;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.048 c
1-1164016150
BasilAKANaiL
2006-11-20 12:49
2007.01.14
Объект из процедурной ссылки


4-1157040768
ph0sgen
2006-08-31 20:12
2007.01.14
hinstance


2-1166615109
smaller
2006-12-20 14:45
2007.01.14
Как поймать щелчок мыши по границе формы?


15-1167038945
WondeRu
2006-12-25 12:29
2007.01.14
В среду сдал на сертификат Microsoft


15-1166689502
Nic (from SAF)
2006-12-21 11:25
2007.01.14
Посмотрел сегодня исходник 2-летней давности