Added some improvements for TBigInt shift left operator

This commit is contained in:
Stefan Müller 2024-05-23 22:01:25 +02:00
parent 4329041353
commit 2df8266d42
2 changed files with 42 additions and 39 deletions

View File

@ -626,49 +626,51 @@ var
begin begin
// Handles shift of zero. // Handles shift of zero.
if A = 0 then if A = 0 then
Result := TBigInt.Zero begin
else begin Result := TBigInt.Zero;
// Determines full digit shifts and bit shifts. Exit;
DivMod(B, CBitsPerDigit, digitShifts, bitShifts); end;
if bitShifts > 0 then // Determines full digit shifts and bit shifts.
DivMod(B, CBitsPerDigit, digitShifts, bitShifts);
if bitShifts > 0 then
begin
reverseShift := CBitsPerDigit - bitShifts;
len := Length(A.FDigits);
lastDigit := A.FDigits[len - 1] >> reverseShift;
newLength := len + digitShifts;
if lastDigit = 0 then
SetLength(Result.FDigits, newLength)
else
SetLength(Result.FDigits, newLength + 1);
// Performs full digit shifts by shifting the access index j for A.FDigits.
Result.FDigits[digitShifts] := A.FDigits[0] << bitShifts;
j := 0;
for i := digitShifts + 1 to newLength - 1 do
begin begin
reverseShift := CBitsPerDigit - bitShifts; // Performs bit shifts.
len := Length(A.FDigits); Result.FDigits[i] := A.FDigits[j] >> reverseShift;
lastDigit := A.FDigits[len - 1] >> reverseShift; Inc(j);
newLength := len + digitShifts; Result.FDigits[i] := Result.FDigits[i] or (A.FDigits[j] << bitShifts);
if lastDigit = 0 then
SetLength(Result.FDigits, newLength)
else
SetLength(Result.FDigits, newLength + 1);
// Performs full digit shifts by shifting the access index j for A.FDigits.
Result.FDigits[digitShifts] := A.FDigits[0] << bitShifts;
j := 0;
for i := digitShifts + 1 to newLength - 1 do
begin
// Performs bit shifts.
Result.FDigits[i] := A.FDigits[j] >> reverseShift;
Inc(j);
Result.FDigits[i] := Result.FDigits[i] or (A.FDigits[j] << bitShifts);
end;
if Length(Result.FDigits) > newLength then
Result.FDigits[newLength] := lastDigit;
end
else begin
// Performs full digit shifts by copy if there are no bit shifts.
len := Length(A.FDigits);
SetLength(Result.FDigits, len + digitShifts);
for i := 0 to digitShifts - 1 do
Result.FDigits[i] := 0;
for i := 0 to len - 1 do
Result.FDigits[i + digitShifts] := A.FDigits[i];
end; end;
Result.FIsNegative := A.IsNegative; if lastDigit > 0 then
Result.FDigits[newLength] := lastDigit;
end
else begin
// Performs full digit shifts by copy if there are no bit shifts.
len := Length(A.FDigits);
SetLength(Result.FDigits, len + digitShifts);
for i := 0 to digitShifts - 1 do
Result.FDigits[i] := 0;
for i := 0 to len - 1 do
Result.FDigits[i + digitShifts] := A.FDigits[i];
end; end;
Result.FIsNegative := A.IsNegative;
end; end;
operator shr(const A: TBigInt; const B: Integer): TBigInt; operator shr(const A: TBigInt; const B: Integer): TBigInt;

View File

@ -732,7 +732,8 @@ end;
{ TBigIntShiftLeftTestCase } { TBigIntShiftLeftTestCase }
procedure TBigIntShiftLeftTestCase.Test(const AHexValueOperand: string; const AShift: Integer; const AHexValueResult: string); procedure TBigIntShiftLeftTestCase.Test(const AHexValueOperand: string; const AShift: Integer; const AHexValueResult:
string);
var var
a, s: TBigInt; a, s: TBigInt;
begin begin