Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

# Random generates values between 0 and 1 for doubles ??? mystery... ???

3 views

### Skybuck Flying

May 14, 2015, 7:47:00 AM5/14/15
to
Hello,

I am a bit mystified about the "Random" routine in Delphi.

When I click "find declaration" in Delphi XE7... it will navigate to a
function which will look like:

function Random(const ARange: Integer): Integer;

So at first glance this function seems to return values between 0 and MaxInt
or so...

However Random is somehow capable of initializing doubles with values
between 0 and 1 ?

How can this be ??? Please clearify/solve this mystery for me ?!?

Example code:

program Project1;

{\$APPTYPE CONSOLE}

{\$R *.res}

uses
System.SysUtils;

var
vIndex : integer;
vDouble : double;
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
for vIndex := 0 to 1000 do
begin
vDouble := Random;
writeln( vDouble:16:16 );
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

Sample of output:

0.7212548679672182
0.2104894851800054
0.4930866835638881
0.6567967527080327
0.3219850626774132
0.5962043243926018
0.5341286454349756
0.4350875786039978
0.1325552123598754
0.5131898613180965
0.7825037101283669
0.7080669899005443
0.2223086454905570
0.4329185977112502
0.9693536832928658
0.7503404992166907
0.8087553470395505
0.4153525677975267
0.0065492829307914
0.9315644309390336
0.5416906108148396
0.4670365999918431
0.4646564479917288
0.5437774641904980

Bye,
Skybuck.

### Skybuck Flying

May 14, 2015, 7:56:26 AM5/14/15
to
Apperently it's creating a bit of a problem for people porting code from
C/C++ to Delphi:

I think I just found a bug in Smart Sweeper from AIJunkie website:

The RandBool seems to produce always False.

When the integer version of Random is used it has to be +1 for example:

Random(2) will generate values between 0 and 1.

However

Random(1-0)+1

Ammounts to:
Random(1) which always returns 0, so this is definetly a bug in Smart
Sweeper's RandBool function...

I think this is another nice example how "inconsistent design" can lead to
problems ! ;)

Random behaves inconsistent for integers/whole numbers vs doubles/floating
points.

// Example program to demonstrate bug:

uses
System.SysUtils;

//returns a random integer between x and y
function RandInt(x, y: Integer): Integer;
begin
Result := Random(y - x) + x;
end;

//returns a random bool
function RandBool: Boolean;
begin
Result := RandInt(0, 1) = 1;
end;

var
vIndex : integer;
begin
try
for vIndex := 0 to 1000 do
begin
writeln( RandBool );
end;

except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

Sample of output:

FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE

Bye,
Skybuck.

### Skybuck Flying

May 14, 2015, 7:58:48 AM5/14/15
to
Here is a little fix for it:

// now I am going to fix it ! ;)
function RandBool: Boolean;
begin
Result := Random( 2 ) = 1;
end;

Bye,
Skybuck/

### Skybuck Flying

May 14, 2015, 8:02:46 AM5/14/15
to
RandBool was/is never used in Smart Sweeper.

So in theory it is bugged, in practice it wasn't a problem.

Bye,
Skybuck.

### Skybuck Flying

May 14, 2015, 11:39:12 AM5/14/15
to
My guess for now it's either:

1. "Compiler magic" ?

or

2. Perhaps function overloading, determined by function return type.

Bye,
Skybuck.

### M Philbrook

May 14, 2015, 9:54:19 PM5/14/15
to
In article <3fcba\$5554c1a0\$5419aafe\$17...@news.ziggo.nl>, skybuck2000
@hotmail.com says...
look at Randomize and Randseed

Jamie

### Skybuck Flying

May 15, 2015, 12:01:36 AM5/15/15
to

"M Philbrook" wrote in message
news:MPG.2fbf1c537...@news.eternal-september.org...
Ok thanks Jamie.

Now that I look a bit further than my Nose long is I come across this:

function Random(const ARange: Integer): Integer;

...

function Random: Extended;

Conclusion:

"Find declaration" in this case sucks and is misleading/confusing !

It doesn't go to the correct location ?!

(I'll consider this a bug in the Delphi product ;) :))

(And a very nasty one !)

Bye,
Skybuck.

### Skybuck Flying

May 20, 2015, 12:45:58 AM5/20/15
to
Mystery solved:

Delphi and perhaps for good reason too.

(Actually it does seem to exist somewhat... but then it all goes to
shit/hell... see below lol ***)

The real reason is: the integer version has a parameter and the
double/extended version does not.

(*** One last question which ghosts through my head is: what if the
parameter was optional ? hmmm)

( I explored this question and it's kinda funny a first in my Delphi
history:
[dcc32 Error] TestProgram.dpr(53): E2251 Ambiguous overloaded call to
'MyTest'
TestProgram.dpr(33): Related method: function MyTest: Double;
TestProgram.dpr(39): Related method: function MyTest(Integer): Integer;
)

I will post the secondary code to generate this error below the first
version.

// first version:
// *** Begin of Test Program ***

program TestProgram;

{

version 0.01 created on 20 may 2015 by Skybuck Flying

(Cause for this test is "Random" returning integer or double based on
variable which is assigned too.

Conclusion for now:

It does not seem to be function overloading which Random is using.

Thus my initial hunch that this might be compiler magic seems to be
warrented/have some merit.

Apperently the real reason for different versions of random is this:

the integer version is "parameterized", the double/extended version is not.

Which is kinda whacky but ok.

}

{\$APPTYPE CONSOLE}

{\$R *.res}

uses
System.SysUtils;

function MyTest : double; overload;
begin
result := 666.666;
end;

{
function MyTest : integer; overload; // *** PROBLEM: identifier redeclared,
perhaps try in a unit ? ***
begin
result := 12345;
end;
}

procedure Main;
var
vInteger : integer;
vDouble : double;
begin
writeln('program started');

{
vInteger := MyTest;
writeln('vInteger: ', vInteger );
}
vDouble := MyTest;
writeln('vDouble: ', vDouble );

vInteger := Random( 5 );
writeln('vInteger: ', vInteger );

vDouble := Random;
writeln('vDouble: ', vDouble );

writeln('program finished');
end;

begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

// *** End of Test Program ***

// second version:
// *** Begin of Test Program ***

program TestProgram;

{

version 0.01 created on 20 may 2015 by Skybuck Flying

(Cause for this test is "Random" returning integer or double based on
variable which is assigned too.

Conclusion for now:

It does not seem to be function overloading which Random is using.

Thus my initial hunch that this might be compiler magic seems to be
warrented/have some merit.

Apperently the real reason for different versions of random is this:

the integer version is "parameterized", the double/extended version is not.

Which is kinda whacky but ok.

version 0.02 creates:

[dcc32 Error] TestProgram.dpr(53): E2251 Ambiguous overloaded call to
'MyTest'
TestProgram.dpr(33): Related method: function MyTest: Double;
TestProgram.dpr(39): Related method: function MyTest(Integer): Integer;

^^^ A first for me I think... kinda funny ^^^ =D

}

{\$APPTYPE CONSOLE}

{\$R *.res}

uses
System.SysUtils;

function MyTest : double; overload;
begin
result := 666.666;
end;

function MyTest( Para : integer = 0 ) : integer; overload; // *** PROBLEM:
identifier redeclared, perhaps try in a unit ? ***
begin
result := 12345;
end;

procedure Main;
var
vInteger : integer;
vDouble : double;
begin
writeln('program started');

vInteger := MyTest;
writeln('vInteger: ', vInteger );

vDouble := MyTest;
writeln('vDouble: ', vDouble );

vInteger := Random( 5 );
writeln('vInteger: ', vInteger );

vDouble := Random;
writeln('vDouble: ', vDouble );

writeln('program finished');
end;

begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;