![]() |
Random() in PurePascal
Hallo,
ich habe mir gerade die Random-Funktion einmal näher angeschaut und mir sind 2 Fragen in den Sinn gekommen. Wieso wird EBX auf Null gesetzt, und dann versucht den Speicher von [EBX+@RandSeed] zu lesen? Das XOR ist doch hier vollkommen überflüssig (Bzw. EBX). Random funktion aus der System.pas:
Delphi-Quellcode:
function Random(const ARange: Integer): Integer;
asm PUSH EBX XOR EBX, EBX //<<<<<< IMUL EDX,[EBX].RandSeed,08088405H INC EDX MOV [EBX].RandSeed,EDX MUL EDX MOV EAX,EDX POP EBX end; Meine übersetzte Funktion gibt andere Werte zurück als die Funktion aus der System.pas. Ich könnte mir Vorstellen, dass es an dem mod liegt. Aber was anderes macht hier doch keinen Sinn, oder?
Delphi-Quellcode:
Meine Übersetzung:
MUL EDX //EAX := EAX * EDX und EDX = ?
Delphi-Quellcode:
function MyRandom2(const ARange: Cardinal): Cardinal;
begin result := Cardinal(RandSeed * $08088405 + 1) mod aRange; RandSeed := result; end; Gruß, Win32 |
Re: Random() in PurePascal
vielleicht ist dir noch nicht aufgefallen, daß RandSeed auch noch verändert wird (sonst würdest du beim nächsten Aufruf deiner Funktion den seben Wert erhalben :zwinker: )
ich hatte mir das mal vor langer Zeit etwa so übersetzt ... glaub ich :gruebel:
Delphi-Quellcode:
aber was mit EBX ist ... k.A.
Function Random(Range: LongInt): LongInt;
Begin RandSeed := Int64(RandSeed) * 134775813 + 1; Result := TLargeIntRec(Int64(Range) * LongWord(RandSeed)).Hi; End; |
Re: Random() in PurePascal
Code:
entspricht
XOR EBX, EBX
Code:
braucht aber weniger Prozessortakte, da 0 nicht erst aus dem Speicher geladen werden muss.
MOV EBX, 0
Ob das heute noch Sinn macht: keine Ahnung. MfG, Bug |
Re: Random() in PurePascal
Zitat:
Zitat:
|
Re: Random() in PurePascal
wenn du dir den erstellten Assemblercode anschaust sollte es klar werden:
004035CD 31DB xor ebx,ebx 004035CF 6993087084000584 imul edx,[ebx+$00847008],$08088405 wird wohl schneller sein als ein mov ebx, randseed imul edx, ebx, $08088405 ----------- Und bei einem mov ebx, 0 wird die 0 (0 als opcode parameter) sehr wohl aus dem speicher geladen |
Re: Random() in PurePascal
Hi brechi,
Zitat:
Delphi-Quellcode:
Das ist doch bestimmt schneller als erst EBX auf 0 zu setzen und dann nochmal auf EBX lesend zugreifen (Das PUSH/POP nicht zu vergessen).
xor ebx,ebx
imul edx,[ebx+$00847008],$08088405 -> imul edx,[0 + $00847008],$08088405 -> imul edx,[$00847008],$08088405 Zitat:
Gruß |
Re: Random() in PurePascal
Bei der ganzen Diskussion mit EBX etc ist doch etwas untergangen, warum der Ausgangscode nicht funktioniert und warum nicht mod benutzt wird. Zum ersten war himitsu ziemlich nahe dran. Hier ein Delphiprogramm, daß exakt random reproduziert (zumindest bis D10):
Delphi-Quellcode:
Ausgabe ist:
program rt;
{$apptype console} {$q-,r-} uses windows,sysutils; var myrandseed: cardinal; function myrandom(range: cardinal): cardinal; begin myrandseed := myrandseed * $08088405 + 1; result := (int64(range) * myrandseed) shr 32; end; var k: integer; r1,r2: cardinal; begin myrandseed := randseed; for k:=1 to 10 do begin r1 := random(100000); r2 := myrandom(100000); writeln(r1:10, r2:10, myrandseed mod 2:4, myrandseed mod 4:4) end; readln; end.
Code:
Die letzen beiden Spalten zeigen, warum mod nicht 'gut' ist: die unteren Bits sind halt nicht besonders zufällig :). 0 0 1 1 . 3137 3137 0 2 . 86104 86104 1 3 . 20258 20258 0 0 . 27292 27292 1 1 . 67165 67165 0 2 . 31869 31869 1 3 . 16179 16179 0 0 . 37223 37223 1 1 . 42567 42567 0 2 Selbst random und die hohen Bits haben eine klein Bias, aber für den Hausgebrauch reichts (für wissenschaftliche Zwecke ist die Periode von random eh zu klein, und für Kryptographie sowieso völlig ungeignet). Gammatester |
Re: Random() in PurePascal
Hallo gammatester,
danke für die ausführliche Erklärung! Ich hatte verdrengt, dass mul das Ergebnis in edx:eax speichert. Und somit immer mit den falschen 4byte gerechnet.
Delphi-Quellcode:
Gruß,
function MyRandom2(const ARange: Cardinal): Cardinal;
begin result := Cardinal(RandSeed * $08088405 + 1) * Int64(ARange) shr 32; RandSeed := result; end; Win32 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:52 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz