blerontin
blerontin

Reputation: 3139

How to get a 64-bit random value in Delphi?

How can I create a random 64-bit integer value in Delphi 2006? The built-in integer-based Random() function seems to return only values between 0 and 2^31.

Upvotes: 5

Views: 3350

Answers (6)

Remko
Remko

Reputation: 7330

Create a GUID (eg CoCreateGuid) and cast it to Int64.

Upvotes: 4

David Heffernan
David Heffernan

Reputation: 612824

Generate two 32 bit randoms and splice them together.

EDIT

Similar to @Andreas's answer I like the following (equivalent) implementation:

function Random64: UInt64;
var
  Overlay: packed record
    a, b: UInt32;
  end absolute Result;
begin
  Assert(SizeOf(Overlay)=SizeOf(Result));
  Overlay.a := Random32;
  Overlay.b := Random32;
end;

Upvotes: 10

Andreas Rejbrand
Andreas Rejbrand

Reputation: 108928

Simple:

function Random64: UInt64;
begin
  PCardinal(@result)^ := Random32;
  PCardinal(cardinal(@result) + 4)^ := Random32;
end;

where Random32 is your favourite 32-bit unsigned integer random number function.

Upvotes: 3

Mitch Schwartz
Mitch Schwartz

Reputation: 1513

You can generate 64 random bits and interpret the result as an integer. (63 bits if you are working with signed integers and want the result to be non-negative.) Equivalently you can take two random integers in the range 0..2^31-1, plus two extra random bits, and concatenate them to get a random 64-bit integer.

EDIT: I was curious about the statistical properties of pseudo-random numbers generated by concatenating pseudo-random components and found that (apparently) this approach might not work well depending on your pseudo-random generator (of course for true random number generation, as from atmospheric noise, concatenating random bits is no problem). For recreational use, the loss of various statistical properties might be acceptable, but for more serious use you might end up needing a custom pseudo-random generator as @gabr suggested. Here is a related question: Best method of generating a number with 256 random bits?

Upvotes: 4

blerontin
blerontin

Reputation: 3139

To answer my own question I came up with the following code:

function GetRandomInt64() : int64;
begin
   Int64Rec(result).Words[0] := Random(High(Word));
   Int64Rec(result).Words[1] := Random(High(Word));
   Int64Rec(result).Words[2] := Random(High(Word));
   Int64Rec(result).Words[3] := Random(High(Word));
end;

Not sure if this is a valid solution or it will always create the same follow-up number X+1 after a given result number X.

Upvotes: 4

gabr
gabr

Reputation: 26830

You can use my GpRandomGen. It implements Marsaglia/Zaman/James algorithm, is extremely fast and supposedly very random. Released as a freeware.

Upvotes: 16

Related Questions