Jump to content

Linear congruential generator: Difference between revisions

no edit summary
(Added solution for EDSAC.)
No edit summary
Line 1,016:
18467
6334</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| Winapi.Windows}}
{{Trans|C#}}
<lang Delphi>
program Linear_congruential_generator;
 
{$APPTYPE CONSOLE}
{$R *.res}
 
uses
System.SysUtils,
Winapi.Windows;
 
type
TRandom = record
private
FSeed: Cardinal;
FBsdCurrent: Cardinal;
FMsvcrtCurrent: Cardinal;
class function Next(seed, a, b: Cardinal): Cardinal; static;
public
constructor Create(const seed: Cardinal);
function Rand(Bsd: Boolean = True): Cardinal;
property Seed: Cardinal read FSeed;
end;
 
{ TRandom }
 
class function TRandom.Next(seed, a, b: Cardinal): Cardinal;
begin
Result := (a * seed + b) and MAXDWORD;
end;
 
function TRandom.Rand(Bsd: Boolean): Cardinal;
begin
if Bsd then
begin
FBsdCurrent := Next(FBsdCurrent, 1103515245, 12345);
Result := FBsdCurrent;
end
else
begin
FMsvcrtCurrent := Next(FMsvcrtCurrent shl 16, 214013, 2531011) shr 16;
Result := FMsvcrtCurrent;
end;
end;
 
constructor TRandom.Create(const seed: Cardinal);
begin
FSeed := seed;
FBsdCurrent := FSeed;
FMsvcrtCurrent := FSeed;
end;
 
var
r: TRandom;
 
procedure PrintRandom(count: Integer; IsBsd: Boolean);
const
NAME: array[Boolean] of string = ('MS', 'BSD');
var
i: Integer;
begin
Writeln(NAME[IsBsd], ' next ', count, ' Random'#10);
for i := 0 to count - 1 do
writeln(' ', r.Rand(IsBsd));
writeln;
end;
 
begin
r.Create(GetTickCount);
PrintRandom(10, True);
PrintRandom(10, False);
readln;
end.
 
</lang>
 
{{out}}
<pre>
BSD next 10 Random
 
3076996592
1668591465
978771438
1655648911
3482994972
245356837
1171712762
1870031019
3901807368
2560221857
 
MS next 10 Random
 
22925
26495
34217
21291
29349
31799
10113
52643
58173
35439
</pre>
=={{header|EDSAC order code}}==
The first version of this solution had trouble with the "sandwich digit". As pointed out by Wilkes, Wheeler & Gill (1951 edition, page 26), a 35-bit constant cannot be loaded via pseudo-orders if the middle bit (sandwich digit) is 1. One workaround, adopted in the EDSAC solution to the Babbage Problem, is to use the negative of the constant instead. The alternative, which WWG evidently preferred and which is used in the LCG solution posted here, is to load 35-bit constants via the library subroutine R9.
478

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.