📄 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 + -