Board index » delphi » randomize

randomize

Can anyone explain the randomize procedure in Delphi?

Thanks.

 

Re:randomize


The randomize procedure just does initialization for the random
generator: if you use the random function without calling randomize e.g.
at program start you will get the same row of values every time you run
your prog.

Daniel Berg

Gavin Coull schrieb:

Quote

> Can anyone explain the randomize procedure in Delphi?

> Thanks.

Re:randomize


Randomize initializes the Random seed by setting it to a "random" (based on
current time) seed. I you don't use Randomize you will get the same row of
numbers when
calling the Random function.

--
Janus N. T?ndering
Email: janusnt<alpha>usa<dot>net
Please correct my email address if you
want to mail me....thanks

Quote
Gavin Coull wrote in message <3576A4B6.6...@abdn.ac.uk>...
>Can anyone explain the randomize procedure in Delphi?

>Thanks.

Re:randomize


In article <3576ec0...@news.euroconnect.dk>, "Janus N?rgaard T?ndering"

Quote
<janusnt<alpha>usa<dot>net> writes:
>Randomize initializes the Random seed by setting it to a "random" (based on
>current time) seed. I you don't use Randomize you will get the same row of
>numbers when
>calling the Random function.

But call Randomize only once in your program, otherwise you lose some
randomality.

Alan Lloyd
alangll...@aol.com

Re:randomize


If you call Randomize and then inspect the RandSeed variable, byte
for byte, you will recognize the 4 values as hour, minute, seconds
and fractions (1/100) of seconds. The resolution (as I remember
from my own test long time ago) is NOT down as fine as
10 miliseconds though.

The technical reason for this must be that the traditional DOS
timer available to programs is updated 18 times/second or once
every 55 milliseconds.

This is not a very effective use of the 32 bits in RandSeed, and I
for one do consider packing the time slightly different, mainly in
order to avoid the possibility of having RandSeed generate the same
starter in the extreme unlikely event that it is run at the exact
same time of day (within some 50 milliseconds) on two separate days,
but also in order to extend the number of possible starters from
Randomize.

regards Sven

Quote
Simon R Knight wrote:

. . . . . (snip)
Quote
> Does anyone know what resolution is represented by the value assigned
> by the "Randomize" method ?

> The (D1) "DecodeTime" method only provides a resolution in 10's of
> milliseconds (ie. 100 th's of a second) for it's millisecond variable,
> but the Float value underlying TDateTime provides lots of digits.

> By calling randomize and checking the Randseed value, there also
> appears enough digits to represent a greater resolution than 100th's
> of a second, so I have been wondering what resolution the last digit
> in Randseed's initialization actually represents ?

. . . . . (snip

Re:randomize


Try:

var
Byte1, Byte2, Byte3, Byte4 byte
Hour, Minute, Second, Sec100 word
...
...
Randomize
GetTime(Hour, Minute, Second, Sec100)
Byte1 := RandSeed shr 24
Byte2 := (RandSeed shr 16) and 255
Byte3 := (RandSeed shr 8) and 255
Byte4 := RandSeed and 255
WriteLn(Byte1, Byte2, Byte3, Byte4)
WriteLn(Hour, Minute, Second, Sec100)

and see if you do not recognize the four values?

(I originally did this in Pascal, but would be
very surprised if it is different in Delphi)

regards Sven

Quote
Simon R Knight wrote:

> On Fri, 05 Jun 1998 08:45:37 +0200, Sven Pran <Sven.P...@alcatel.no>
> wrote:

> >If you call Randomize and then inspect the RandSeed variable, byte
> >for byte, you will recognize the 4 values as hour, minute, seconds
> >and fractions (1/100) of seconds.

> How have you arrive at this? I have inspected the Randseed variable,
> and there are no values in it that correspond to hours or minutes.
> (D1).

. . . . . (snip)

Re:randomize


In article <3576B4EC.73697...@cip.physik.uni-oldenburg.de>,
  Daniel Berg <b...@cip.physik.uni-oldenburg.de> wrote:

Quote

> The randomize procedure just does initialization for the random
> generator: if you use the random function without calling randomize e.g.
> at program start you will get the same row of values every time you run
> your prog.

       Right. Sometimes people conclude from this that calling
Randomize repeatedly will make a sequence even more random.
Lest someone think that, someone should point out that that's
wrong wrong wrong. In fact if you say

for j:=0 to 10 do
begin
  randomize;
  Data[j]:= random(42);
end;

there's a good chance that the numbers in Data will all be the
same. The thing to do is to call Randomize exactly _once_
during execution of the program. Like in the form's OnCreate
or some such place.

David C. Ullrich

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading

Re:randomize


On Fri, 05 Jun 1998 17:30:59 GMT, s...@bigfoot.com (Simon R Knight)
wrote:

Quote
>On Fri, 05 Jun 1998 16:01:30 +0200, Sven Pran <Sven.P...@alcatel.no>
>wrote:

<snippity-snip-snip>

Excuse me for the discourse interruptus, but...

<shaking head> THAT's how one recognizes Real Programmers: They will
spend hours discussing a highly technical issue that has little value
in the real world. <grin>

Is there much sense in worrying about the possible range of RandSeed,
when the Random() function itself is predictable? Wouldn't it make
more sense to find an alternative algorithm that produces "more random
than Random" numbers? A large number of alternatives are available.

My personal favorite (to paraphrase Ray Arachelian):

For the generation of random numbers, you should take your randseed
and sort it (be sure to use Quick Sort here, and not bubble sort!),
that is put all the 1 bits to the right, all the 0 bits to the left,
and the {*word*194} bits in your head.  Then take the result and express
it as 2^X-1, and extract X. Once you have X, repeat the process until
X=2.

With me so far?  Good, now you have to extract the {*word*194} bits from
your mind, and let N express them.  Your S boxes are now comprised of
X+Ni which you can simply express as 2+Ni.  Now, if you recall, Ni is
the symbol for nickel, which is what this algorithm is worth $2.05
payable in Monopoly dollars.  If you've been following the news,
you'll know that Microsoft is a monopoly and therefore
weighs the same as a duck.  Since ducks float, and wood also floats,
ducks must weigh the same as wood, and therefore are witches.
Multiply this by the flight speed of an unladen African swallow, and
divide it by the flight speed of a laden european swallow, then add
your favorite color, and substract your name.

Simple, isn't it?

Re:randomize


On Sun, 07 Jun 1998 18:59:00 GMT, s...@bigfoot.com (Simon R Knight)
wrote:

Quote
>Anyone have the Delphi code for the "Randomize" procedure?
>I only have a few source files with my D1/D3.

At the risk of being sued, the code follows below. Hm - first time
I've looked at this routine. It's obvious why you see the Randomize
value change so quickly over time - but also equally obvious that the
value doesn't change THAT much in terms of a difference between one
value and the next.

procedure       Randomize;
var
        systemTime :
        record
                wYear   : Word;
                wMonth  : Word;
                wDayOfWeek      : Word;
                wDay    : Word;
                wHour   : Word;
                wMinute : Word;
                wSecond : Word;
                wMilliSeconds: Word;
                reserved        : array [0..7] of char;
        end;
asm
        LEA     EAX,systemTime
        PUSH    EAX
        CALL    GetSystemTime
        MOVZX   EAX,systemTime.wHour
        IMUL    EAX,60
        ADD     AX,systemTime.wMinute   { sum = hours * 60 + minutes

Quote
}

        IMUL    EAX,60
        XOR     EDX,EDX
        MOV     DX,systemTime.wSecond
        ADD     EAX,EDX                 { sum = sum * 60 + seconds
Quote
}

        IMUL    EAX,1000
        MOV     DX,systemTime.wMilliSeconds
        ADD     EAX,EDX                 { sum = sum * 1000 +
milliseconds       }
        MOV     RandSeed,EAX
end;

If I'm to be sued, I might as well make it worth their while:

procedure       _RandInt;
asm
{     ->EAX     Range   }
{     <-EAX     Result  }
        IMUL    EDX,RandSeed,08088405H
        INC     EDX
        MOV     RandSeed,EDX
        MUL     EDX
        MOV     EAX,EDX
end;

procedure       _RandExt;
const   Minus32: double = -32.0;
asm
{       FUNCTION _RandExt: Extended;    }
{     ->EAX     Range   }

        IMUL    EDX,RandSeed,08088405H
        INC     EDX
        MOV     RandSeed,EDX

        FLD     Minus32
        PUSH    0
        PUSH    EDX
        FILD    qword ptr [ESP]
        ADD     ESP,8
        FSCALE
        FSTP    ST(1)
end;

all of which is very interesting (it's a slow night).

Heck, I had expected rather more intricate functions - but I suppose
Borland figured people who needed better pseudo-random numbers would
make the effort to find these elsewhere.

Quote
>I recall that there are one or two components "out there" which
>provide time resolution down to one microsecond or less, derived in
>some way from the processor cycles. In the context of the above, it
>would be interesting to know if the Randseed value provided by
>"Randomize" is also derived from processor cycles, or simply a process
>of division.

As you can see, it's not that fancy. Have you done a lookup on
AltaVista yet?

Quote
>>My personal favorite (to paraphrase Ray Arachelian):
>Yes !  ... I must implement this tonight, in my chloroform quantum
>computer.

Huh! your R&D dept is going in the exact opposite direction to ours -
and your guys have it wrong. A computer as small as that WILL NOT GET
YOU CHICKS. Trust me.

Re:randomize


I believe this settles the question, a few comments added below

regards Sven

. . . . . (snip)

Quote
>procedure       Randomize;

. . . . . (snip: SystemTime record description)

Quote
>asm
>        LEA     EAX,systemTime
>        PUSH    EAX
>        CALL    GetSystemTime
>        MOVZX   EAX,systemTime.wHour
>        IMUL    EAX,60
>        ADD     AX,systemTime.wMinute   { sum = hours * 60 + minutes }
>        IMUL    EAX,60
>        XOR     EDX,EDX
>        MOV     DX,systemTime.wSecond
>        ADD     EAX,EDX         { sum = sum * 60 + seconds }
>        IMUL    EAX,1000
>        MOV     DX,systemTime.wMilliSeconds
>        ADD     EAX,EDX         { sum = sum * 1000 + milliseconds }
>        MOV     RandSeed,EAX
>end;

So Randomize indeed retrieves RandSeed from the system clock,
but in a slightly different manner from what I found in my Pascal
compilers (TP 5.5 and later versions).

. . . . . (snip)

Quote
>procedure       _RandInt;
>asm
>{     ->EAX     Range   }
>{     <-EAX     Result  }
>        IMUL    EDX,RandSeed,08088405H
>        INC     EDX
>        MOV     RandSeed,EDX
>        MUL     EDX
>        MOV     EAX,EDX
>end;

. . . . . (snip)

Quote
>but I suppose Borland figured people who needed better
>pseudo-random numbers would make the effort to find these
>elsewhere.

What is so bad with this code, haven't you guys read Knuth?

With properly selected constants he shows that for most statistical
purposes the Lehmer algorithm (which this still seems to be) is in
fact among the best suitable pseudo random generators available.

Of course, being a linear algorithm it cannot be used for any kind of
cryptography, but that has never been the purpose of pseudo random
generators so I can hardly believe this is a relevant argument.

. . . . . (snip)

Thanks for giving the samples !
 Sven

Re:randomize


Quote
Simon R Knight wrote:
> I never seem to get away from AltaVista. Yes  ... I did a search for a
> more random number generator, but I was unable to find quite what I
> was looking for, i.e. a fine D1/D3 component for random number
> generation, that would impress the hell out of me.
> Simon

Simon,

I seem have have some fairly good random number generator code from a
1985 vintage Modula-2 compiler (the company that produced it is no
longer is business, so I think I might survive...).

The important thing to notice in this context is that CARDINAL is
unsigned 16 bit, INTEGER is signed 16 bit, and REAL is a single
precision real.

If you wanted to port it to D2/3 ... I'd leave the actual engine well
alone (keep it all 16bit), because the workings of it are really quite
subtle, and if you want to produce 32 or 64 bit random values, then just
fill the high and low words with random stuff separately. You can then
use this to create random double and extended precision floating points
numbers.

Oh yeah ... and relace the DOS call with something sensible!

CONST
  HistoryMax = 54;

VAR
  HistoryPtr : CARDINAL;
  LowerPtr   : CARDINAL;
VAR
  History    : ARRAY [0..HistoryMax] OF CARDINAL;

PROCEDURE SetUpHistory(Seed: CARDINAL);
VAR
  x : LONGCARD;
  i : CARDINAL;
BEGIN
  HistoryPtr := HistoryMax;
  LowerPtr := 23;
  x := LONGCARD(Seed);
  i := 0;
  REPEAT
    x := (x*3141592621+17);
    History[i] := CARDINAL(x DIV 10000H);
    INC(i);
  UNTIL i>HistoryMax;
END SetUpHistory;

PROCEDURE RANDOM(Range: CARDINAL) : CARDINAL;
VAR res:CARDINAL;
BEGIN
  IF HistoryPtr = 0 THEN
    IF LowerPtr = 0 THEN
      SetUpHistory(12345);
    ELSE
      HistoryPtr := HistoryMax;
      LowerPtr   := LowerPtr-1;
    END;
  ELSE
    HistoryPtr := HistoryPtr-1;
    IF LowerPtr = 0 THEN
      LowerPtr := HistoryMax;
    ELSE
      LowerPtr := LowerPtr-1;
    END;
  END;
  res := History[HistoryPtr]+History[LowerPtr];
  History[HistoryPtr] := res;
  IF Range = 0 THEN
    RETURN res;
  ELSE
    RETURN res MOD Range;
  END;
END RANDOM;

PROCEDURE RANDOMIZE;
VAR R : Registers;
BEGIN
  WITH R DO
    AH := 2CH;
    Dos(R);
    SetUpHistory(DX+CX);
  END;
END RANDOMIZE;

PROCEDURE RAND(): REAL;
VAR
  x:RECORD low,high:CARDINAL END;
BEGIN
  x.low := RANDOM(0);
  x.high := RANDOM(0);
  RETURN REAL(LONGCARD(x))/(REAL(MAX(LONGCARD))+1.0);
END RAND;

--
***********************************************
Martin Harvey
email: mc...@harvey27.demon.co.uk
Web pages: http://www.harvey27.demon.co.uk/mch24/

Make your machine part of the fastest computer
on earth. See http://www.distributed.net/
***********************************************

Re:randomize


Oh yeah ... just one more thing. The original compiler pragmas elsewhere
in the source indicate that overflow checking should be turned off for
these procedures. The length of the data is thus used to ensure that all
integer operations are mod 2^16

MH.

Quote
Simon R Knight wrote:

> On Mon, 08 Jun 1998 14:10:07 +0100, Martin Harvey
> <mc...@hermes.cam.ac.uk> wrote:

> >Simon,

> >I seem have have some fairly good random number generator code from a
> >1985 vintage Modula-2 compiler (the company that produced it is no
> >longer is business, so I think I might survive...).

> <snip>

> <snip>

> Thanks Martin !  ... I'll have a play with it.

> Simon.

--
***********************************************
Martin Harvey
email: mc...@harvey27.demon.co.uk
Web pages: http://www.harvey27.demon.co.uk/mch24/

Make your machine part of the fastest computer
on earth. See http://www.distributed.net/
***********************************************

Re:randomize


In article <3576B4EC.73697...@cip.physik.uni-oldenburg.de>, Daniel Berg
<b...@cip.physik.uni-oldenburg.de> writes

If you include the mmsystem unit by doing

  uses mmsystem;

you can then call timegettime which changes much more frequently (its
supposed to be accurtate to 1ms) than the built in timer used by
randomize (which changes every 55ms);

randseed:= timegettime;

The chances of the program running at exactly the same time (in
millisecs since bootup) is probably very very low indeed.

Quote
>The randomize procedure just does initialization for the random
>generator: if you use the random function without calling randomize e.g.
>at program start you will get the same row of values every time you run
>your prog.

>Daniel Berg

>Gavin Coull schrieb:

>> Can anyone explain the randomize procedure in Delphi?

>> Thanks.

--
David H. Bolton

Re:randomize


David,

  I would have to disagree with you on this point. If this were the sort
of program which would be placed in the Startup group or otherwise
automatically started at bootup, the likelihood that timegettime would
return the exact same result would be GREATLY increased. Generating truly
random numbers has always been a difficult task, and while in some cases
this solution would be adequate, I wouldn't wouldn't want to rely on it
myself. Popular sources of randomness include interval length between
keystrokes, mouse movements, sampling data from unused ports (like the
microphone input from your sound card), or anything else which relies on
other "outside" information.

Jim.

David H. Bolton <da...@codecraft.demon.co.uk> wrote:
: In article <3576B4EC.73697...@cip.physik.uni-oldenburg.de>, Daniel Berg
: <b...@cip.physik.uni-oldenburg.de> writes

: If you include the mmsystem unit by doing

:   uses mmsystem;

: you can then call timegettime which changes much more frequently (its
: supposed to be accurtate to 1ms) than the built in timer used by
: randomize (which changes every 55ms);

: randseed:= timegettime;

: The chances of the program running at exactly the same time (in
: millisecs since bootup) is probably very very low indeed.

[snipsnipsnip]

: David H. Bolton

--
------------------------------------------------------------------------------
Jim Kirk                   These opinions do not necessarily represent those
Weblogix                   of my employer. If you agree with them, they are
jk...@primenet.com         mine. If you disagree, they are someone else's.
------------------------------------------------------------------------------

Re:randomize


Quote
>  I would have to disagree with you on this point. If this were the sort
>of program which would be placed in the Startup group or otherwise
>automatically started at bootup, the likelihood that timegettime would
>return the exact same result would be GREATLY increased. Generating truly
>random numbers has always been a difficult task, and while in some cases
>this solution would be adequate, I wouldn't wouldn't want to rely on it
>myself. Popular sources of randomness include interval length between
>keystrokes, mouse movements, sampling data from unused ports (like the
>microphone input from your sound card), or anything else which relies on
>other "outside" information.

Hmmm. I would have thought that "outside" information is not a good
source of random number seeds. I suspect that my keystrokes and mouse
movements are depressingly predicatable to quite a high degree of
accuracy. I am not a sociologist/anthropoloist but I doubt that any
behavioural patterns are suffiently random.

Getting a random seed from an "artificial" source such as milliseconds
since X from a computer timer has got to be better since it is *much*
harder for a human to influence the result.

All IMHO, of course.
--
Jeremy Collins
Kansai Business Systems

(return address not altered 'coz I get spammed *whatever* I do!)

Go to page: [1] [2]

Other Threads