📄 fgint.pas
字号:
if (Trest > 2147483647) then
rest := 0
else
rest := -1;
end;
size := size1;
while (Sum.Number[size] = 0) and (size > 1) do
size := size - 1;
if size < size1 then
begin
SetLength(Sum.Number, size + 1);
end;
Sum.Number[0] := size;
Sum.Sign := FGInt1.Sign;
end;
end;
end;
end;
procedure FGIntChangeSign(var FGInt: TFGInt);
begin
if FGInt.Sign = negative then
FGInt.Sign := positive
else
FGInt.Sign := negative;
end;
// Substract 2 FGInts, FGInt1 - FGInt2 = dif
procedure FGIntSub(var FGInt1, FGInt2, dif: TFGInt);
begin
FGIntChangeSign(FGInt2);
FGIntadd(FGInt1, FGInt2, dif);
FGIntChangeSign(FGInt2);
end;
// multiply a FGInt by an integer, FGInt * by = res, by < 1000000000
procedure FGIntMulByInt(const FGInt: TFGInt; var res: TFGInt; by: int64);
var
i, size: longint;
Trest, rest: int64;
begin
size := FGInt.Number[0];
SetLength(res.Number, size + 2);
rest := 0;
for i := 1 to size do
begin
Trest := FGInt.Number[i] * by + rest;
res.Number[i] := Trest and 2147483647;
rest := Trest shr 31;
end;
if rest <> 0 then
begin
size := size + 1;
res.Number[size] := rest;
end
else
SetLength(res.Number, size + 1);
res.Number[0] := size;
res.Sign := FGInt.Sign;
end;
// multiply a FGInt by an integer, FGInt * by = res, by < 1000000000
procedure FGIntMulByIntbis(var FGInt: TFGInt; by: int64);
var
i, size: longint;
Trest, rest: int64;
begin
size := FGInt.Number[0];
SetLength(FGInt.Number, size + 2);
rest := 0;
for i := 1 to size do
begin
Trest := FGInt.Number[i] * by + rest;
FGInt.Number[i] := Trest and 2147483647;
rest := Trest shr 31;
end;
if rest <> 0 then
begin
size := size + 1;
FGInt.Number[size] := rest;
end
else
SetLength(FGInt.Number, size + 1);
FGInt.Number[0] := size;
end;
// divide a FGInt by an integer, FGInt = res * by + modres
procedure FGIntDivByInt(const FGInt: TFGInt; var res: TFGInt; by: int64; var modres: int64);
var
i, size: longint;
rest: int64;
begin
size := FGInt.Number[0];
SetLength(res.Number, size + 1);
modres := 0;
for i := size downto 1 do
begin
modres := modres shl 31;
rest := modres or FGInt.Number[i];
res.Number[i] := rest div by;
modres := rest mod by;
end;
while (res.Number[size] = 0) and (size > 1) do
size := size - 1;
SetLength(res.Number, size + 1);
res.Number[0] := size;
res.Sign := FGInt.Sign;
end;
// divide a FGInt by an integer, FGInt = FGInt * by + modres
procedure FGIntDivByIntBis(var FGInt: TFGInt; by: int64; var modres: int64);
var
i, size: longint;
rest: int64;
begin
size := FGInt.Number[0];
modres := 0;
for i := size downto 1 do
begin
modres := modres shl 31;
rest := modres or FGInt.Number[i];
FGInt.Number[i] := rest div by;
modres := rest mod by;
end;
while (FGInt.Number[size] = 0) and (size > 1) do
size := size - 1;
if size <> FGInt.Number[0] then
begin
SetLength(FGInt.Number, size + 1);
FGInt.Number[0] := size;
end;
end;
// Reduce a FGInt modulo by (=an integer), FGInt mod by = modres
procedure FGIntModByInt(const FGInt: TFGInt; by: int64; var modres: int64);
var
i, size: longint;
rest: int64;
begin
size := FGInt.Number[0];
modres := 0;
for i := size downto 1 do
begin
modres := modres shl 31;
rest := modres + FGInt.Number[i];
modres := rest mod by;
end;
end;
// Returns the FGInt in absolute value
procedure FGIntAbs(var FGInt: TFGInt);
begin
FGInt.Sign := positive;
end;
// Copy a FGInt1 into FGInt2
procedure FGIntCopy(const FGInt1: TFGInt; var FGInt2: TFGInt);
begin
FGInt2.Sign := FGInt1.Sign;
FGInt2.Number := nil;
FGInt2.Number := copy(FGInt1.Number, 0, FGInt1.Number[0] + 1);
end;
// Shift the FGInt to the left in base 2 notation, ie FGInt = FGInt * 2
procedure FGIntShiftLeft(var FGInt: TFGInt);
var
L, m: int64;
i, size: longint;
begin
size := FGInt.Number[0];
L := 0;
for i := 1 to size do
begin
m := FGInt.Number[i] shr 30;
FGInt.Number[i] := ((FGInt.Number[i] shl 1) or L) and 2147483647;
L := m;
end;
if L <> 0 then
begin
SetLength(FGInt.Number, size + 2);
FGInt.Number[size + 1] := L;
FGInt.Number[0] := size + 1;
end;
end;
// Shift the FGInt to the right in base 2 notation, ie FGInt = FGInt div 2
procedure FGIntShiftRight(var FGInt: TFGInt);
var
L, m: int64;
i, size: longint;
begin
size := FGInt.Number[0];
L := 0;
for i := size downto 1 do
begin
m := FGInt.Number[i] and 1;
FGInt.Number[i] := (FGInt.Number[i] shr 1) or L;
L := m shl 30;
end;
if (FGInt.Number[size] = 0) and (size > 1) then
begin
SetLength(FGInt.Number, size);
FGInt.Number[0] := size - 1;
end;
end;
// FGInt = FGInt / 2147483648
procedure FGIntShiftRightBy31(var FGInt: TFGInt);
var
size: longint;
begin
size := FGInt.Number[0];
if size > 1 then
begin
FGInt.Number := copy(FGInt.Number, 1, size);
FGInt.Number[0] := size - 1;
end
else
FGInt.Number[1] := 0;
end;
// FGInt1 = FGInt1 + FGInt2, FGInt1 > FGInt2
procedure FGIntAddBis(var FGInt1: TFGInt; const FGInt2: TFGInt);
var
i, size1, size2: longint;
rest: integer;
Trest: int64;
begin
size1 := FGInt1.Number[0];
size2 := FGInt2.Number[0];
rest := 0;
for i := 1 to size2 do
begin
Trest := FGInt1.Number[i] + FGInt2.Number[i] + rest;
rest := Trest shr 31;
FGInt1.Number[i] := Trest and 2147483647;
end;
for i := size2 + 1 to size1 do
begin
Trest := FGInt1.Number[i] + rest;
rest := Trest shr 31;
FGInt1.Number[i] := Trest and 2147483647;
end;
if rest <> 0 then
begin
SetLength(FGInt1.Number, size1 + 2);
FGInt1.Number[0] := size1 + 1;
FGInt1.Number[size1 + 1] := rest;
end;
end;
// FGInt1 = FGInt1 - FGInt2, use only when 0 < FGInt2 < FGInt1
procedure FGIntSubBis(var FGInt1: TFGInt; const FGInt2: TFGInt);
var
i, size1, size2: longint;
rest: integer;
Trest: int64;
begin
size1 := FGInt1.Number[0];
size2 := FGInt2.Number[0];
rest := 0;
for i := 1 to size2 do
begin
Trest := 2147483648 + FGInt1.Number[i] - FGInt2.Number[i] + rest;
if (Trest > 2147483647) then
rest := 0
else
rest := -1;
FGInt1.Number[i] := Trest and 2147483647;
end;
for i := size2 + 1 to size1 do
begin
Trest := 2147483648 + FGInt1.Number[i] + rest;
if (Trest > 2147483647) then
rest := 0
else
rest := -1;
FGInt1.Number[i] := Trest and 2147483647;
end;
i := size1;
while (FGInt1.Number[i] = 0) and (i > 1) do
i := i - 1;
if i < size1 then
begin
SetLength(FGInt1.Number, i + 1);
FGInt1.Number[0] := i;
end;
end;
// Multiply 2 FGInts, FGInt1 * FGInt2 = Prod
procedure FGIntMul(const FGInt1, FGInt2: TFGInt; var Prod: TFGInt);
var
i, j, size, size1, size2: longint;
rest, Trest: int64;
begin
size1 := FGInt1.Number[0];
size2 := FGInt2.Number[0];
size := size1 + size2;
SetLength(Prod.Number, size + 1);
for i := 1 to size do
Prod.Number[i] := 0;
for i := 1 to size2 do
begin
rest := 0;
for j := 1 to size1 do
begin
Trest := Prod.Number[j + i - 1] + FGInt1.Number[j] * FGInt2.Number[i] + rest;
Prod.Number[j + i - 1] := Trest and 2147483647;
rest := Trest shr 31;
end;
Prod.Number[i + size1] := rest;
end;
Prod.Number[0] := size;
while (Prod.Number[size] = 0) and (size > 1) do
size := size - 1;
if size < Prod.Number[0] then
begin
SetLength(Prod.Number, size + 1);
Prod.Number[0] := size;
end;
if FGInt1.Sign = FGInt2.Sign then
Prod.Sign := positive
else
Prod.Sign := negative;
end;
// Square a FGInt, FGInt
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -