Linear congruential generator: Difference between revisions
Content added Content deleted
(Added solution for EDSAC.) |
MaiconSoft (talk | contribs) No edit summary |
||
Line 1,016: | Line 1,016: | ||
18467 |
18467 |
||
6334</pre> |
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}}== |
=={{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. |
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. |