Improvement of BIRegularMultiply
from 'lagprogramming'.
packages/fcl-hash/src/fptlsbigint.pas has
function BIRegularMultiply(var Context: TBigIntContext; BIA, BIB: PBigInt; InnerPartial, OuterPartial: Integer): PBigInt;
var
Carry: TBIComponent;
BIR: PBigInt;
I, J, N, RIndex, T: Integer;
SA, SB, SR:PBIComponent;
Tmp: TBILongComponent;
begin
if not BICheck(BIA^) or not BICheck(BIB^) then
begin
Result:=nil;
Exit;
end;
I := 0;
N := BIA^.Size;
T := BIB^.Size;
BIR := BIAllocate(Context, N+T);
SR := BIR^.Components;
SA := BIA^.Components;
SB := BIB^.Components;
FillByte(BIR^.Components^, (N+T) * BIGINT_COMP_BYTE_SIZE, 0);
repeat
Carry := 0;
RIndex := I;
J := 0;
if (OuterPartial > I) and (OuterPartial < N) then
begin
RIndex := OuterPartial-1;
J := OuterPartial-I-1;
end;
repeat
if (InnerPartial > 0) and (RIndex >= InnerPartial) then
Break;
Tmp := TBILongComponent(SR[RIndex]) + TBILongComponent(SA[J]) * SB[I] + Carry; // Avoid overflow
SR[RIndex] := TBIComponent(Tmp and $ffffffff); // Downsize
Inc(RIndex);
Carry := Tmp shr BIGINT_COMP_BIT_SIZE;
Inc(J);
until J >= N;
SR[RIndex] := Carry;
Inc(I);
until I >= T;
BIRelease(Context,BIA);
BIRelease(Context,BIB);
BITrim(BIR);
Result := BIR;
end;
The statement "if (OuterPartial > 0) and ((OuterPartial-I) > 0) and (OuterPartial < N) then" can be rewritten as "if (OuterPartial > 0) and (OuterPartial > I) and (OuterPartial < N) then". The minimum value of variable I inside the repeat loop is 0, which makes the presence of the "(OuterPartial > 0)" condition redundant.
The following patch replaces "if (OuterPartial > 0) and ((OuterPartial-I) > 0) and (OuterPartial < N) then" with "if (OuterPartial > I) and (OuterPartial < N) then".
Edited by Alexey Torgashin