NRnd(var A: IInteger; Bits: Integer = 0; Sign: Boolean = False; Random: TRandom = nil); overload;
Bits gibt dabei die Größe=Wertebereich des IInteger's in A an der erzeugt werden soll.
Also bei NRnd(A, 64); wird A im Bereich von 2^63 <= A < 2^64 sein, ergo A hat garantiert eine Größe von 64 Bits. Dieses Verhalten ist bei der Anwendung von großen Zahlen, sei es für Kryptographie, Mathematik ect. pp. am häufigsten erwünscht. Meistens muß man eben Zufallszahlen erzeugen (zb. Primzahlen) die exakt X Bits groß sind.
Wird Sign == TRUE gesetzt so wird auch das Vorzeichen per Zufall erzeugt, ansonsten bleibt es wie es ist.
Du kannst aber auch Bits == 0 übergeben. Dann wird intern Bits per Zufall im Bereich von 1 bis 2048 liegen, d.h. die Function NRnd() erzeugt dann Zufallszahlen im Bereich von 0 <= A < 2^2048
Statt NCut() hättest du dann NBit(A, NHigh(A), False); nehmen können, dies dürfte schneller sein.
Wie du am nachfolgendem Source von NRnd() erkennen kannst kann Bits < 0 sein. Zb. mit NRnd(A, -64); würdest du Zahlen im Bereich von 0 <= A < 2^64 erzeugen. Also im Grunde das was du suchtest. Ok, der negative Bits Parameter ist ziemlich versteckt allerdings benötigt man solche Zufallszahlen fast niemals. Zumindestens ich brauchte diese Funktionalität nur ein einzigstes mal bisher.
Dein NCut() Aufruf wirkt mathematisch wie ein NMod(A, 2^16), sprich Modulare Division.
Falls du Zb. Zahlen im Bereich von 100.000 <= A < 1.000.000 erzeugen wolltest dann sähe dies so aus
Delphi-Quellcode:
NRnd(A, -32);
NMod(A, 1000000 - 100000);
NAdd(A, 100000);
Gruß Hagen
Delphi-Quellcode:
procedure NRnd(
var A: IInteger; Bits: Integer = 0; Sign: Boolean = False; Random: TRandom =
nil);
var
I: Integer;
begin
with NAllocNew(A)^
do
begin
if Random =
nil then Random := RND;
if Bits = 0
then Bits := Random.Int(256 * 8);
if Bits = 0
then
begin
FCount := 0;
FNeg := False;
end else
begin
if Bits < 0
then
begin
Bits := -Bits;
I := (Bits + 31)
shr 5;
if Cardinal(I) > FSize
then NSetCount(A, I, cfNoFill)
else FCount := I;
Random.Buffer(FNum^, I * 4);
Dec(I);
Bits := FNum[I]
and ($FFFFFFFF
shr (32 - Bits
and 31));
FNum[I] := Bits;
if Bits = 0
then NNormalize(A);
end else
repeat
I := (Bits + 31)
shr 5 +1;
if Cardinal(I) > FSize
then NSetCount(A, I, cfNoFill)
else FCount := I;
Random.Buffer(FNum^, I * 4);
if FNum[I] = 0
then NNormalize(A);
I := NSize(A) - Bits;
if I > 0
then NShr(A, I);
until I >= 0;
if Sign
then FNeg := Random.Int(2) = 1;
end;
end;
end;