Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Random 64 bit


This question is answered.


Permlink Replies: 24 - Last Post: Aug 31, 2016 10:32 AM Last Post By: Andrej Mrvar
Andrej Mrvar

Posts: 99
Registered: 10/20/10
Random 64 bit  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 2:19 AM
It seems that random is not able to return int64 as a result? Am I right?
How can I generate a random int64 number then (e.g. number in range 1..10,000,000,000)?
Thanks.
Andrej
Andrej Mrvar

Posts: 99
Registered: 10/20/10
Re: Random 64 bit  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 2:22 AM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Is trunc(10000000000 * random) + 1 precise enough?

A.
Michael Rabatsc...

Posts: 125
Registered: 1/22/07
Re: Random 64 bit  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 2:34 AM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Am 03.08.2016 um 11:22 schrieb Andrej Mrvar:
Is 10000000000 * random precise enough?

A.
No... The base is still a longword

Yo could do something like this (note there would be still a little
problem - the numbers are up to 31 bits due to the fact that integer is
used instead of longword):

fucntion rand64(aRange : Int64) : int64;
begin
Result := ( int64(Random(MaxInt)) shl 32 ) or
( int64(Random(MaxInt)) )
mod aRange;
end;
Andrej Mrvar

Posts: 99
Registered: 10/20/10
Re: Random 64 bit  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 4:39 AM   in response to: Michael Rabatsc... in response to: Michael Rabatsc...
Thanks.

Probably mod should be executed at the end, therefore instead of

Result := ( int64(Random(MaxInt)) shl 32 ) or ( int64(Random(MaxInt)) ) mod aRange;
it should be
Result := ( ( int64(Random(MaxInt)) shl 32 ) or ( int64(Random(MaxInt)) ) ) mod aRange;

with additional ( and )

?
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Random 64 bit  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 5:45 AM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Den 8/3/2016 kl. 13:39 skrev Andrej Mrvar:
Thanks.

Probably mod should be executed at the end, therefore instead of

Result := ( int64(Random(MaxInt)) shl 32 ) or ( int64(Random(MaxInt)) ) mod aRange;
it should be
Result := ( ( int64(Random(MaxInt)) shl 32 ) or ( int64(Random(MaxInt)) ) ) mod aRange;

with additional ( and )

?

https://sites.google.com/site/kbbsoft/delphi-progamming

best regards
Kim/C4D
Andrej Mrvar

Posts: 99
Registered: 10/20/10
Re: Random 64 bit  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 6:54 AM   in response to: Kim Madsen in response to: Kim Madsen
Thanks for providing this list. That is a lot of work behind indeed.
I am a bit lost with all this possibilities.
Maybe you can suggest a simple random function
to use to get integers in range 1 up to 10^10 (or 10^12 at most).
Actually I do not need the whole range of 64 bit integers.
Thanks in advance.
A.
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 9:09 AM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Den 8/3/2016 kl. 15:54 skrev Andrej Mrvar:
Thanks for providing this list. That is a lot of work behind indeed.
I am a bit lost with all this possibilities.
Maybe you can suggest a simple random function
to use to get integers in range 1 up to 10^10 (or 10^12 at most).
Actually I do not need the whole range of 64 bit integers.
Thanks in advance.
A.

Whats your criteria for the random function?

Consider:

- Trueness? (ie.. is pseudo random good enough or must it rely on
physical randomness?)
- Speed?
- Distribution of values?
- Period? (how many random number generations before you start to see it
starting over with the same list of "random" numbers)

Its kind of a science to pick the best one for the job :)

A simple pseudo random generator is the LCG. Its using last value
generated to create next value.

https://en.wikipedia.org/wiki/Linear_congruential_generator

A function can easily be created for generating 64 bit psudo random LCG
values like this:

TRand64 = class
private
class var FValue:uint64;
public
class procedure Seed(const AValue:uint64);
class function Rand:uint64;
end;

class procedure TRand64.Seed(const AValue:uint64);
begin
FValue:=AValue;
end;

class procedure TRand64.Rand:uint64;
begin
FValue:=(uint64(6364136223846793005)*FValue +
uint64(1442695040888963407)) AND $FFFFFFFFFFFFFFFF;
Result:=FValue;
end;

Freely written. I havnt tried to compile it, but it ought to work :)

best regards
Kim/C4D

Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 9:24 AM   in response to: Kim Madsen in response to: Kim Madsen
Den 8/3/2016 kl. 18:09 skrev Kim Madsen:
class procedure TRand64.Rand:uint64;
begin
...

Ofcourse that should be

class function TRand64.Rand:uint64;
begin
...

Andrej Mrvar

Posts: 99
Registered: 10/20/10
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 2:06 PM   in response to: Kim Madsen in response to: Kim Madsen
Thanks for providing the detailed solution. It works.

But I wonder if the following solution is faster?

Since I only need random numbers lower than 10^12 that is approx. 2^40, 40 bits=5 bytes, this 5 bytes should be sufficient:
8 bytes of the 64 bit integer result I fill in the following way:
- the lower five bytes with random values,
- the highest 3 bytes set to 0:

Int64Rec(Result).Words[0] := Random(High(Word));
Int64Rec(Result).Words[1] := Random(High(Word));
Int64Rec(Result).Bytes[4] := Random(High(Byte));
Int64Rec(Result).Bytes[5] := 0;
Int64Rec(Result).Words[3] := 0;

Result:=Result mod (maxvalue); // maxvalue is for example 1000000000000

Is that ok?
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 4:08 PM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Den 8/3/2016 kl. 23:06 skrev Andrej Mrvar:
Thanks for providing the detailed solution. It works.

But I wonder if the following solution is faster?

Since I only need random numbers lower than 10^12 that is approx. 2^40, 40 bits=5 bytes, this 5 bytes should be sufficient:
8 bytes of the 64 bit integer result I fill in the following way:
- the lower five bytes with random values,
- the highest 3 bytes set to 0:

Int64Rec(Result).Words[0] := Random(High(Word));
Int64Rec(Result).Words[1] := Random(High(Word));
Int64Rec(Result).Bytes[4] := Random(High(Byte));
Int64Rec(Result).Bytes[5] := 0;
Int64Rec(Result).Words[3] := 0;

Result:=Result mod (maxvalue); // maxvalue is for example 1000000000000

Is that ok?

Hi,

It will provide you with some sort of randomness, but it wont be faster,
and the period of that combination of random values is unknown. It may
end up actually having a pretty bad randomness.

Further it will be slower since Random is called multiple times, and
internall Random makes something similar (although with different
constants) to the one I provided.

If you want a 40 bit random value, you can change it to:

class function TRand64.Rand:uint64;
begin
FValue:=(uint64(6364136223846793005)*FValue +
uint64(1442695040888963407)) MOD uint64($10000000000);
Result:=FValue;
end;

best regards
Kim/C4D
Andrej Mrvar

Posts: 99
Registered: 10/20/10
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 10:16 PM   in response to: Kim Madsen in response to: Kim Madsen
Thanks for explanation and the updated function for generating 40 bit random integer.
I do not see how to use correctly?
Should I first call TRand64.Seed with some number to initialize it (like randomize)?
And later TRand64.Rand.

Please provide me with an example of declarations needed and correct call of your function to obtain
the random 40 bit integer..

Thanks.
Andrej
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 4, 2016 2:20 AM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Den 8/4/2016 kl. 07:16 skrev Andrej Mrvar:
Thanks for explanation and the updated function for generating 40 bit random integer.
I do not see how to use correctly?
Should I first call TRand64.Seed with some number to initialize it (like randomize)?
And later TRand64.Rand.

Please provide me with an example of declarations needed and correct call of your function to obtain
the random 40 bit integer..

Thanks.
Andrej

Hi,

Yes you ought to set Seed to something. There are two ways to use it:

A) You set it to some fixed value (for example 0) everytime you want to
have your "random" number sequence to start over from start. This
obviously makes the random number non random, but instead predictable.
Thats useful for creating test cases, where you want to be sure to
compare a fixed outcome of some algorithm requiring random numbers.

B) You can set it once in start of your application, to a value based on
a time function. Like GetTickCount or similar changing value. This makes
the "random" sequence unpredictable, which more resembles true
randomness, and is what should typically be used when you run your
application.

After that you use the Rand function as many times as you need.

best regards
Kim/C4D

The best n-tier for the best developers
www.components4developers.com
Andrej Mrvar

Posts: 99
Registered: 10/20/10
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 4, 2016 3:22 AM   in response to: Kim Madsen in response to: Kim Madsen
Thanks, I see.

A simple random number generator for generating integer numbers in range 1 to 10 billions would be also

x := Random(1,000,000,000) + Random(10)*1,000,000,000

i.e. generating random number between 0 and one billion (standard random generator, since that is still 32 bit)) and than add zero, one, two, three ,..., or 9 billions by random.

Am I right? Would that be random enough?
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 4, 2016 5:22 AM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Den 8/4/2016 kl. 12:22 skrev Andrej Mrvar:
Thanks, I see.

A simple random number generator for generating integer numbers in range 1 to 10 billions would be also

x := Random(1,000,000,000) + Random(10)*1,000,000,000

i.e. generating random number between 0 and one billion (standard random generator, since that is still 32 bit)) and than add zero, one, two, three ,..., or 9 billions by random.

Am I right? Would that be random enough?

Hi,

As I wrote, using Random multiple times potentially results in unknown
periods and randomness. It may be good enough for your purpose, but only
you know what you actually need.

It will also be slower, but again, it may be fast enough for your purpose.

Please check my previous replies on that topic.

best regards
Kim/C4D

The best n-tier for the best developers
http://www.components4developers.com
Andrej Mrvar

Posts: 99
Registered: 10/20/10
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 4, 2016 7:13 AM   in response to: Kim Madsen in response to: Kim Madsen
Thanks again for your answer.
I can understand that your function is more random.

One final question:
would it be possible to rewrite your function in 'plain' pascal,
I mean without defining new objects, classes,
just function which returns int64 as a result?

I just want to keep things as simple as possible ;)
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Random 64 bit [Edit]
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 4, 2016 9:14 AM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Den 8/4/2016 kl. 16:13 skrev Andrej Mrvar:
Thanks again for your answer.
I can understand that your function is more random.

One final question:
would it be possible to rewrite your function in 'plain' pascal,
I mean without defining new objects, classes,
just function which returns int64 as a result?

I just want to keep things as simple as possible ;)

Hi,

unit xxxx;

interface

procedure Seed(const AValue:uint64);
function Rand:uint64;

implementation

var FValue:uint64;

procedure Seed(const AValue:uint64);
begin
FValue:=AValue;
end;

function Rand:uint64;
begin
FValue:=(uint64(6364136223846793005)*FValue +
uint64(1442695040888963407)) MOD uint64($10000000000);
Result:=FValue;
end;

best regards
Kim/C4D
Andrej Mrvar

Posts: 99
Registered: 10/20/10
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 4, 2016 1:17 PM   in response to: Kim Madsen in response to: Kim Madsen
Thanks for your patience ;)

Now I included it to my program - the function is much simpler and
according to testing also faster than other functions that I have tried before.

And now a 'final final' two questions:

For the starting value of FValue I take random 32 (actually 31) bit integer which is generated by Delphi itself:

FValue:=uint64(random(maxint));

maybe:
FValue:= uint64(random(maxint)) * uint64(random(maxint)) );
would be better?

Since I finally need a int64 as a result, I divide the FValue by two, to avoid negative values:

Result:= int64(FValue div 2) mod 10000000000;

Do you agree with this or should I do it differently?

Best.
Andrej
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Random 64 bit [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 5, 2016 1:06 AM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Hi,

That should be fine.

Although I personally would want to use Seed function to set the
starting value (which can be anything as long as it fits in a 64 bit
unsigned integer).

This way you can reseed (when you need to), to a previous value and get
the same "random" values again and again for testing purposes.

When you run in production, you can seed it with random or gettickcount
or trunc(now*10000)-trunc(now) or something like that.
As long as the value is depending on "external circumstances" like a
counter or a Real time clock or something with enough precision to make
the seed start seem unpredictable.

best regards
Kim/C4D

Den 8/5/2016 kl. 08:30 skrev Andrej Mrvar:

Thanks for your patience ;)

Now I included it to my program - the function is much simpler and
according to testing also faster than other functions that I have tried before.

And now a 'final final' two questions:

For the starting value of FValue I take random 32 (actually 31) bit integer which is generated by Delphi itself:

FValue:=uint64(random(maxint));

maybe:
FValue:= uint64(random(maxint)) * uint64(random(maxint)) );
would be better?

Since I finally need a int64 as a result, I divide the FValue by two, to avoid negative values:

Result:= int64(FValue div 2) mod 10000000000;

Do you agree with this or should I do it differently?

Best.
Andrej
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Random 64 bit [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 5, 2016 1:09 AM   in response to: Kim Madsen in response to: Kim Madsen
BTW, you dont need to divide by 2 if you want the result in an int64.

You asked for the function only to return 40 bits of the possible 64
bits, so you will be able to cast the value directly to int64 without
problems.

best regards
Kim/C4D
Andrej Mrvar

Posts: 99
Registered: 10/20/10
Re: Random 64 bit [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 5, 2016 2:27 AM   in response to: Kim Madsen in response to: Kim Madsen
Thanks again. Problem solved now. No more questions ;)
Best wishes.
Andrej
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 9, 2016 12:39 AM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Andrej Mrvar wrote:

Is trunc(10000000000 * random) + 1 precise enough?

A.

No. Just generate two random Integers and do:

MyRandomInt64 := Int64(RandomInt1) shl 32 or RandomInt2;

--
Rudy Velthuis http://www.rvelthuis.de

"This isn't life in the fast lane, it's life in the oncoming traffic."
-- Terry Pratchett
Andrej Mrvar

Posts: 99
Registered: 10/20/10
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 10, 2016 1:30 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
No. Just generate two random Integers and do:
MyRandomInt64 := Int64(RandomInt1) shl 32 or RandomInt2;

As I learned ;) there is at least one problem with this solution:
Delphi random generator gives you random 31 bit number and not 32 bit number.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 10, 2016 3:02 AM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Andrej Mrvar wrote:

No. Just generate two random Integers and do:
MyRandomInt64 := Int64(RandomInt1) shl 32 or RandomInt2;

As I learned ;) there is at least one problem with this solution:
Delphi random generator gives you random 31 bit number and not 32 bit
number.

That's right. Simply do:

RandomInt1 := RandSeed;
Random(MaxInt);
RandomInt2 := RandSeed;
MyRandomInt64 := Int64(RandomInt1) shl 32 or RandomInt2;

--
Rudy Velthuis http://www.rvelthuis.de

"Every day people are straying away from the church and going
back to God."
-- Lenny Bruce
Michael Rabatsc...

Posts: 125
Registered: 1/22/07
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 29, 2016 3:21 AM   in response to: Andrej Mrvar in response to: Andrej Mrvar
Am 10.08.2016 um 10:30 schrieb Andrej Mrvar:
No. Just generate two random Integers and do:
MyRandomInt64 := Int64(RandomInt1) shl 32 or RandomInt2;

As I learned ;) there is at least one problem with this solution:
Delphi random generator gives you random 31 bit number and not 32 bit number.

Hey you can check out my random generator class from the mrMath library

-> it got an implementation of the mersenne twister random generator. It
results in an 32 bit value but it's "periodicity" is 2^19937 - 1
-> it also got an interface to the os random number functions as well as
the Intel RDRAND assembler instruction.

( https://en.wikipedia.org/wiki/Mersenne_Twister)

check it out on:

https://github.com/mikerabat/mrmath

kind regards
Mike
Andrej Mrvar

Posts: 99
Registered: 10/20/10
Re: Random 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 31, 2016 10:32 AM   in response to: Michael Rabatsc... in response to: Michael Rabatsc...
Function provided by Kim Madsen worked just fine for me so I included it into my program.
Thanks anyway.
Andrej
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02