Added some improvements for TBigInt shift left operator
This commit is contained in:
parent
4329041353
commit
2df8266d42
78
UBigInt.pas
78
UBigInt.pas
|
@ -626,49 +626,51 @@ var
|
|||
begin
|
||||
// Handles shift of zero.
|
||||
if A = 0 then
|
||||
Result := TBigInt.Zero
|
||||
else begin
|
||||
// Determines full digit shifts and bit shifts.
|
||||
DivMod(B, CBitsPerDigit, digitShifts, bitShifts);
|
||||
begin
|
||||
Result := TBigInt.Zero;
|
||||
Exit;
|
||||
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
|
||||
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
|
||||
// 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];
|
||||
// Performs bit shifts.
|
||||
Result.FDigits[i] := A.FDigits[j] >> reverseShift;
|
||||
Inc(j);
|
||||
Result.FDigits[i] := Result.FDigits[i] or (A.FDigits[j] << bitShifts);
|
||||
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;
|
||||
|
||||
Result.FIsNegative := A.IsNegative;
|
||||
end;
|
||||
|
||||
operator shr(const A: TBigInt; const B: Integer): TBigInt;
|
||||
|
|
|
@ -732,7 +732,8 @@ end;
|
|||
|
||||
{ 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
|
||||
a, s: TBigInt;
|
||||
begin
|
||||
|
|
Loading…
Reference in New Issue