|
@@ -0,0 +1,2041 @@
|
|
|
+{ %norun }
|
|
|
+
|
|
|
+{ *********************************************************** }
|
|
|
+{ * Numerics(32/64).dll import for Pascal * }
|
|
|
+{ * ------------------------------------------------------- * }
|
|
|
+{ * set const LibName = 'numerics32.dll' * }
|
|
|
+{ * to import numerics32.dll; * }
|
|
|
+{ * set const LibName = 'numerics64.dll' * }
|
|
|
+{ * to import numerics64.dll; * }
|
|
|
+{ *********************************************************** }
|
|
|
+
|
|
|
+{
|
|
|
+ Copyright (c) 2013 Sergey Kasandrov
|
|
|
+
|
|
|
+ Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
+ of this software and associated documentation files (the "Software"), to deal
|
|
|
+ in the Software without restriction, including without limitation the rights
|
|
|
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
+ copies of the Software, and to permit persons to whom the Software is
|
|
|
+ furnished to do so, subject to the following conditions:
|
|
|
+
|
|
|
+ The above copyright notice and this permission notice shall be included in
|
|
|
+ all copies or substantial portions of the Software.
|
|
|
+
|
|
|
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
+ THE SOFTWARE.
|
|
|
+}
|
|
|
+
|
|
|
+unit tw26266;
|
|
|
+
|
|
|
+{$mode delphi}
|
|
|
+
|
|
|
+interface
|
|
|
+
|
|
|
+uses SysUtils;
|
|
|
+
|
|
|
+type
|
|
|
+ TF_RESULT = LongInt;
|
|
|
+
|
|
|
+const
|
|
|
+ // = common microsoft codes =
|
|
|
+ TF_S_OK = TF_RESULT(0); // Operation successful
|
|
|
+ TF_S_FALSE = TF_RESULT(1); // Operation successful
|
|
|
+ TF_E_FAIL = TF_RESULT($80004005); // Unspecified failure
|
|
|
+ TF_E_INVALIDARG = TF_RESULT($80070057); // One or more arguments are not valid
|
|
|
+ TF_E_NOINTERFACE = TF_RESULT($80004002); // No such interface supported
|
|
|
+ TF_E_NOTIMPL = TF_RESULT($80004001); // Not implemented
|
|
|
+ TF_E_OUTOFMEMORY = TF_RESULT($8007000E); // Failed to allocate necessary memory
|
|
|
+ TF_E_UNEXPECTED = TF_RESULT($8000FFFF); // Unexpected failure
|
|
|
+
|
|
|
+ // = TFL specific codes =
|
|
|
+ TF_E_NOMEMORY = TF_RESULT($A0000003); // specific TFL memory error
|
|
|
+ TF_E_LOADERROR = TF_RESULT($A0000004); // Error loading dll
|
|
|
+
|
|
|
+{$IFDEF FPC}
|
|
|
+type
|
|
|
+ TBytes = array of Byte;
|
|
|
+{$ENDIF}
|
|
|
+
|
|
|
+type
|
|
|
+ IBigNumber = interface
|
|
|
+
|
|
|
+ function GetIsEven: Boolean; stdcall;
|
|
|
+ function GetIsOne: Boolean; stdcall;
|
|
|
+ function GetIsPowerOfTwo: Boolean; stdcall;
|
|
|
+ function GetIsZero: Boolean; stdcall;
|
|
|
+ function GetSign: Integer; stdcall;
|
|
|
+ function GetSize: Integer; stdcall;
|
|
|
+
|
|
|
+ function CompareNumber(Num: IBigNumber): Integer; stdcall;
|
|
|
+ function CompareNumberU(Num: IBigNumber): Integer; stdcall;
|
|
|
+
|
|
|
+ function AddNumber(Num: IBigNumber; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function AddNumberU(Num: IBigNumber; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function SubNumber(Num: IBigNumber; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function SubNumberU(Num: IBigNumber; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function MulNumber(Num: IBigNumber; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function MulNumberU(Num: IBigNumber; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function DivRemNumber(Num: IBigNumber; var Q, R: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function DivRemNumberU(Num: IBigNumber; var Q, R: IBigNumber): TF_RESULT; stdcall;
|
|
|
+
|
|
|
+ function AndNumber(Num: IBigNumber; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function AndNumberU(Num: IBigNumber; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function OrNumber(Num: IBigNumber; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function OrNumberU(Num: IBigNumber; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function XorNumber(Num: IBigNumber; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+
|
|
|
+ function ShlNumber(Shift: Cardinal; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function ShrNumber(Shift: Cardinal; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+
|
|
|
+ function AssignNumber(var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function AbsNumber(var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function NegateNumber(var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function Pow(Value: Cardinal; var IRes: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function PowU(Value: Cardinal; var IRes: IBigNumber): TF_RESULT; stdcall;
|
|
|
+
|
|
|
+ function SqrtNumber(var IRes: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function GCD(B: IBigNumber; var G: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function EGCD(B: IBigNumber; var G, X, Y: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function ModPow(IExp, IMod: IBigNumber; var IRes: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function ModInverse(M: IBigNumber; var R: IBigNumber): TF_RESULT; stdcall;
|
|
|
+
|
|
|
+ function ToLimb(var Value: UInt32): TF_RESULT; stdcall;
|
|
|
+ function ToIntLimb(var Value: Int32): TF_RESULT; stdcall;
|
|
|
+ function ToDec(P: PByte; var L: Integer): TF_RESULT; stdcall;
|
|
|
+ function ToHex(P: PByte; var L: Integer; TwoCompl: Boolean): TF_RESULT; stdcall;
|
|
|
+ function ToPByte(P: PByte; var L: Cardinal): TF_RESULT; stdcall;
|
|
|
+
|
|
|
+ function CompareToLimb(B: UInt32): Integer; stdcall;
|
|
|
+ function CompareToLimbU(B: UInt32): Integer; stdcall;
|
|
|
+ function CompareToIntLimb(B: Int32): Integer; stdcall;
|
|
|
+ function CompareToIntLimbU(B: Int32): Integer; stdcall;
|
|
|
+
|
|
|
+ function AddLimb(Limb: LongWord; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function AddLimbU(Limb: LongWord; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function AddIntLimb(Limb: LongInt; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+
|
|
|
+ function SubLimb(Limb: LongWord; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function SubLimb2(Limb: LongWord; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function SubLimbU(Limb: LongWord; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function SubLimbU2(Limb: LongWord; var Res: LongWord): TF_RESULT; stdcall;
|
|
|
+ function SubIntLimb(Limb: LongInt; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function SubIntLimb2(Limb: LongInt; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+
|
|
|
+ function MulLimb(Limb: LongWord; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function MulLimbU(Limb: LongWord; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function MulIntLimb(Limb: LongInt; var Res: IBigNumber): TF_RESULT; stdcall;
|
|
|
+
|
|
|
+ function DivRemLimb(Limb: LongWord; var Q: IBigNumber; var R: IBigNumber): TF_RESULT; stdcall;
|
|
|
+ function DivRemLimb2(Limb: LongWord; var Q: IBigNumber; var R: LongWord): TF_RESULT; stdcall;
|
|
|
+ function DivRemLimbU(Limb: LongWord; var Q: IBigNumber; var R: LongWord): TF_RESULT; stdcall;
|
|
|
+ function DivRemLimbU2(Limb: LongWord; var Q: LongWord; var R: LongWord): TF_RESULT; stdcall;
|
|
|
+ function DivRemIntLimb(Limb: LongInt; var Q: IBigNumber; var R: LongInt): TF_RESULT; stdcall;
|
|
|
+ function DivRemIntLimb2(Limb: LongInt; var Q: LongInt; var R: LongInt): TF_RESULT; stdcall;
|
|
|
+
|
|
|
+ function ToDblLimb(var Value: UInt64): TF_RESULT; stdcall;
|
|
|
+ function ToDblIntLimb(var Value: Int64): TF_RESULT; stdcall;
|
|
|
+ function CompareToDblLimb(B: UInt64): Integer; stdcall;
|
|
|
+ function CompareToDblLimbU(B: UInt64): Integer; stdcall;
|
|
|
+ function CompareToDblIntLimb(B: Int64): Integer; stdcall;
|
|
|
+ function CompareToDblIntLimbU(B: Int64): Integer; stdcall;
|
|
|
+ end;
|
|
|
+
|
|
|
+type
|
|
|
+ BigCardinal = record
|
|
|
+ private
|
|
|
+ FNumber: IBigNumber;
|
|
|
+ public
|
|
|
+ function ToString: string;
|
|
|
+ function ToHexString(Digits: Integer = 0; const Prefix: string = '';
|
|
|
+ TwoCompl: Boolean = False): string;
|
|
|
+ function ToBytes: TBytes;
|
|
|
+ function TryParse(const S: string; TwoCompl: Boolean = False): Boolean;
|
|
|
+ procedure Free;
|
|
|
+
|
|
|
+ class function Compare(const A, B: BigCardinal): Integer; static;
|
|
|
+ function CompareTo(const B: BigCardinal): Integer; overload; inline;
|
|
|
+
|
|
|
+ class function Pow(const Base: BigCardinal; Value: Cardinal): BigCardinal; static;
|
|
|
+ class function DivRem(const Dividend, Divisor: BigCardinal;
|
|
|
+ var Remainder: BigCardinal): BigCardinal; overload; static;
|
|
|
+
|
|
|
+ class operator Explicit(const Value: BigCardinal): Cardinal;
|
|
|
+ class operator Explicit(const Value: BigCardinal): Integer;
|
|
|
+ class operator Explicit(const Value: BigCardinal): UInt64;
|
|
|
+ class operator Explicit(const Value: BigCardinal): Int64;
|
|
|
+ class operator Implicit(const Value: Cardinal): BigCardinal;
|
|
|
+ class operator Implicit(const Value: UInt64): BigCardinal;
|
|
|
+ class operator Explicit(const Value: Integer): BigCardinal;
|
|
|
+ class operator Explicit(const Value: Int64): BigCardinal;
|
|
|
+ class operator Explicit(const Value: TBytes): BigCardinal;
|
|
|
+ class operator Explicit(const Value: string): BigCardinal;
|
|
|
+
|
|
|
+ class operator Equal(const A, B: BigCardinal): Boolean; inline;
|
|
|
+ class operator NotEqual(const A, B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A, B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A, B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThan(const A, B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A, B: BigCardinal): Boolean; inline;
|
|
|
+
|
|
|
+ class operator Add(const A, B: BigCardinal): BigCardinal;
|
|
|
+ class operator Subtract(const A, B: BigCardinal): BigCardinal;
|
|
|
+ class operator Multiply(const A, B: BigCardinal): BigCardinal;
|
|
|
+ class operator IntDivide(const A, B: BigCardinal): BigCardinal;
|
|
|
+ class operator Modulus(const A, B: BigCardinal): BigCardinal;
|
|
|
+
|
|
|
+ class operator LeftShift(const A: BigCardinal; Shift: Cardinal): BigCardinal;
|
|
|
+ class operator RightShift(const A: BigCardinal; Shift: Cardinal): BigCardinal;
|
|
|
+
|
|
|
+ class operator BitwiseAnd(const A, B: BigCardinal): BigCardinal;
|
|
|
+ class operator BitwiseOr(const A, B: BigCardinal): BigCardinal;
|
|
|
+
|
|
|
+ function CompareToCard(const B: Cardinal): Integer;
|
|
|
+ function CompareToInt(const B: Integer): Integer;
|
|
|
+ function CompareTo(const B: Cardinal): Integer; overload; inline;
|
|
|
+ function CompareTo(const B: Integer): Integer; overload; inline;
|
|
|
+
|
|
|
+ class operator Equal(const A: BigCardinal; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator Equal(const A: Cardinal; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator Equal(const A: BigCardinal; const B: Integer): Boolean; inline;
|
|
|
+ class operator Equal(const A: Integer; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: BigCardinal; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: Cardinal; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: BigCardinal; const B: Integer): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: Integer; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: BigCardinal; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: Cardinal; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: BigCardinal; const B: Integer): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: Integer; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: BigCardinal; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: Cardinal; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: BigCardinal; const B: Integer): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: Integer; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThan(const A: BigCardinal; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator LessThan(const A: Cardinal; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThan(const A: BigCardinal; const B: Integer): Boolean; inline;
|
|
|
+ class operator LessThan(const A: Integer; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: BigCardinal; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: Cardinal; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: BigCardinal; const B: Integer): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: Integer; const B: BigCardinal): Boolean; inline;
|
|
|
+
|
|
|
+ function CompareToUInt64(const B: UInt64): Integer;
|
|
|
+ function CompareToInt64(const B: Int64): Integer;
|
|
|
+ function CompareTo(const B: UInt64): Integer; overload; inline;
|
|
|
+ function CompareTo(const B: Int64): Integer; overload; inline;
|
|
|
+
|
|
|
+ class operator Equal(const A: BigCardinal; const B: UInt64): Boolean; inline;
|
|
|
+ class operator Equal(const A: UInt64; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator Equal(const A: BigCardinal; const B: Int64): Boolean; inline;
|
|
|
+ class operator Equal(const A: Int64; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: BigCardinal; const B: UInt64): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: UInt64; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: BigCardinal; const B: Int64): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: Int64; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: BigCardinal; const B: UInt64): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: UInt64; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: BigCardinal; const B: Int64): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: Int64; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: BigCardinal; const B: UInt64): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: UInt64; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: BigCardinal; const B: Int64): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: Int64; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThan(const A: BigCardinal; const B: UInt64): Boolean; inline;
|
|
|
+ class operator LessThan(const A: UInt64; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThan(const A: BigCardinal; const B: Int64): Boolean; inline;
|
|
|
+ class operator LessThan(const A: Int64; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: BigCardinal; const B: UInt64): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: UInt64; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: BigCardinal; const B: Int64): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: Int64; const B: BigCardinal): Boolean; inline;
|
|
|
+
|
|
|
+ class function DivRem(const Dividend: BigCardinal; Divisor: Cardinal;
|
|
|
+ var Remainder: Cardinal): BigCardinal; overload; static;
|
|
|
+ class function DivRem(const Dividend: Cardinal; Divisor: BigCardinal;
|
|
|
+ var Remainder: Cardinal): Cardinal; overload; static;
|
|
|
+
|
|
|
+ class operator Add(const A: BigCardinal; const B: Cardinal): BigCardinal;
|
|
|
+ class operator Add(const A: Cardinal; const B: BigCardinal): BigCardinal;
|
|
|
+ class operator Subtract(const A: BigCardinal; const B: Cardinal): BigCardinal;
|
|
|
+ class operator Subtract(const A: Cardinal; const B: BigCardinal): Cardinal;
|
|
|
+ class operator Multiply(const A: BigCardinal; const B: Cardinal): BigCardinal;
|
|
|
+ class operator Multiply(const A: Cardinal; const B: BigCardinal): BigCardinal;
|
|
|
+ class operator IntDivide(const A: BigCardinal; const B: Cardinal): BigCardinal;
|
|
|
+ class operator IntDivide(const A: Cardinal; const B: BigCardinal): Cardinal;
|
|
|
+ class operator Modulus(const A: BigCardinal; const B: Cardinal): Cardinal;
|
|
|
+ class operator Modulus(const A: Cardinal; const B: BigCardinal): Cardinal;
|
|
|
+ end;
|
|
|
+
|
|
|
+ BigInteger = record
|
|
|
+ private
|
|
|
+ FNumber: IBigNumber;
|
|
|
+ function GetSign: Integer;
|
|
|
+ public
|
|
|
+ function ToString: string;
|
|
|
+ function ToHexString(Digits: Integer = 0; const Prefix: string = '';
|
|
|
+ TwoCompl: Boolean = False): string;
|
|
|
+ function ToBytes: TBytes;
|
|
|
+ function TryParse(const S: string; TwoCompl: Boolean = False): Boolean;
|
|
|
+ procedure Free;
|
|
|
+
|
|
|
+ property Sign: Integer read GetSign;
|
|
|
+
|
|
|
+ class function Abs(const A: BigInteger): BigInteger; static;
|
|
|
+ class function Pow(const Base: BigInteger; Value: Cardinal): BigInteger; static;
|
|
|
+ class function DivRem(const Dividend, Divisor: BigInteger;
|
|
|
+ var Remainder: BigInteger): BigInteger; overload; static;
|
|
|
+
|
|
|
+ class function Sqrt(A: BigInteger): BigInteger; static;
|
|
|
+ class function GCD(A, B: BigInteger): BigInteger; static;
|
|
|
+ class function EGCD(A, B: BigInteger; var X, Y: BigInteger): BigInteger; static;
|
|
|
+ class function ModPow(const BaseValue, ExpValue, Modulo: BigInteger): BigInteger; static;
|
|
|
+ class function ModInverse(A, Modulo: BigInteger): BigInteger; static;
|
|
|
+
|
|
|
+ class operator Implicit(const Value: BigCardinal): BigInteger; inline;
|
|
|
+ class operator Explicit(const Value: BigInteger): BigCardinal; inline;
|
|
|
+
|
|
|
+ class operator Explicit(const Value: BigInteger): Cardinal;
|
|
|
+ class operator Explicit(const Value: BigInteger): UInt64;
|
|
|
+ class operator Explicit(const Value: BigInteger): Integer;
|
|
|
+ class operator Explicit(const Value: BigInteger): Int64;
|
|
|
+ class operator Implicit(const Value: UInt32): BigInteger;
|
|
|
+ class operator Implicit(const Value: UInt64): BigInteger;
|
|
|
+ class operator Implicit(const Value: Int32): BigInteger;
|
|
|
+ class operator Implicit(const Value: Int64): BigInteger;
|
|
|
+ class operator Explicit(const Value: TBytes): BigInteger;
|
|
|
+ class operator Explicit(const Value: string): BigInteger;
|
|
|
+
|
|
|
+ class function Compare(const A, B: BigInteger): Integer; overload; static;
|
|
|
+ class function Compare(const A: BigInteger; const B: BigCardinal): Integer; overload; static;
|
|
|
+ class function Compare(const A: BigCardinal; const B: BigInteger): Integer; overload; static;
|
|
|
+ function CompareTo(const B: BigInteger): Integer; overload; inline;
|
|
|
+ function CompareTo(const B: BigCardinal): Integer; overload; inline;
|
|
|
+
|
|
|
+ class operator Equal(const A, B: BigInteger): Boolean; inline;
|
|
|
+ class operator Equal(const A: BigInteger; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator Equal(const A: BigCardinal; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator NotEqual(const A, B: BigInteger): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: BigInteger; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: BigCardinal; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A, B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: BigInteger; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: BigCardinal; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A, B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: BigInteger; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: BigCardinal; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThan(const A, B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThan(const A: BigInteger; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThan(const A: BigCardinal; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A, B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: BigInteger; const B: BigCardinal): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: BigCardinal; const B: BigInteger): Boolean; inline;
|
|
|
+
|
|
|
+ class operator Add(const A, B: BigInteger): BigInteger;
|
|
|
+ class operator Subtract(const A, B: BigInteger): BigInteger;
|
|
|
+ class operator Multiply(const A, B: BigInteger): BigInteger;
|
|
|
+ class operator IntDivide(const A, B: BigInteger): BigInteger;
|
|
|
+ class operator Modulus(const A, B: BigInteger): BigInteger;
|
|
|
+
|
|
|
+ class operator LeftShift(const A: BigInteger; Shift: Cardinal): BigInteger;
|
|
|
+ class operator RightShift(const A: BigInteger; Shift: Cardinal): BigInteger;
|
|
|
+
|
|
|
+ class operator BitwiseAnd(const A, B: BigInteger): BigInteger;
|
|
|
+ class operator BitwiseOr(const A, B: BigInteger): BigInteger;
|
|
|
+ class operator BitwiseXor(const A, B: BigInteger): BigInteger;
|
|
|
+
|
|
|
+ function CompareToCard(const B: Cardinal): Integer;
|
|
|
+ function CompareToInt(const B: Integer): Integer;
|
|
|
+ function CompareTo(const B: Cardinal): Integer; overload; inline;
|
|
|
+ function CompareTo(const B: Integer): Integer; overload; inline;
|
|
|
+ class operator Equal(const A: BigInteger; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator Equal(const A: Cardinal; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator Equal(const A: BigInteger; const B: Integer): Boolean; inline;
|
|
|
+ class operator Equal(const A: Integer; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: BigInteger; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: Cardinal; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: BigInteger; const B: Integer): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: Integer; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: BigInteger; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: Cardinal; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: BigInteger; const B: Integer): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: Integer; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: BigInteger; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: Cardinal; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: BigInteger; const B: Integer): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: Integer; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThan(const A: BigInteger; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator LessThan(const A: Cardinal; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThan(const A: BigInteger; const B: Integer): Boolean; inline;
|
|
|
+ class operator LessThan(const A: Integer; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: BigInteger; const B: Cardinal): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: Cardinal; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: BigInteger; const B: Integer): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: Integer; const B: BigInteger): Boolean; inline;
|
|
|
+
|
|
|
+ function CompareToDoubleUInt(const B: UInt64): Integer;
|
|
|
+ function CompareToDoubleInt(const B: Int64): Integer;
|
|
|
+ function CompareTo(const B: UInt64): Integer; overload; inline;
|
|
|
+ function CompareTo(const B: Int64): Integer; overload; inline;
|
|
|
+
|
|
|
+ class operator Equal(const A: BigInteger; const B: UInt64): Boolean; inline;
|
|
|
+ class operator Equal(const A: UInt64; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator Equal(const A: BigInteger; const B: Int64): Boolean; inline;
|
|
|
+ class operator Equal(const A: Int64; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: BigInteger; const B: UInt64): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: UInt64; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: BigInteger; const B: Int64): Boolean; inline;
|
|
|
+ class operator NotEqual(const A: Int64; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: BigInteger; const B: UInt64): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: UInt64; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: BigInteger; const B: Int64): Boolean; inline;
|
|
|
+ class operator GreaterThan(const A: Int64; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: BigInteger; const B: UInt64): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: UInt64; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: BigInteger; const B: Int64): Boolean; inline;
|
|
|
+ class operator GreaterThanOrEqual(const A: Int64; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThan(const A: BigInteger; const B: UInt64): Boolean; inline;
|
|
|
+ class operator LessThan(const A: UInt64; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThan(const A: BigInteger; const B: Int64): Boolean; inline;
|
|
|
+ class operator LessThan(const A: Int64; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: BigInteger; const B: UInt64): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: UInt64; const B: BigInteger): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: BigInteger; const B: Int64): Boolean; inline;
|
|
|
+ class operator LessThanOrEqual(const A: Int64; const B: BigInteger): Boolean; inline;
|
|
|
+
|
|
|
+// arithmetic operations on BigInteger & Cardinal
|
|
|
+ class operator Add(const A: BigInteger; const B: Cardinal): BigInteger;
|
|
|
+ class operator Subtract(const A: BigInteger; const B: Cardinal): BigInteger;
|
|
|
+ class operator Multiply(const A: BigInteger; const B: Cardinal): BigInteger;
|
|
|
+ class operator IntDivide(const A: BigInteger; const B: Cardinal): BigInteger;
|
|
|
+ class operator Modulus(const A: BigInteger; const B: Cardinal): BigInteger;
|
|
|
+ class function DivRem(const Dividend: BigInteger; const Divisor: Cardinal;
|
|
|
+ var Remainder: BigInteger): BigInteger; overload; static;
|
|
|
+
|
|
|
+// arithmetic operations on Cardinal & BigInteger
|
|
|
+ class operator Add(const A: Cardinal; const B: BigInteger): BigInteger;
|
|
|
+ class operator Subtract(const A: Cardinal; const B: BigInteger): BigInteger;
|
|
|
+ class operator Multiply(const A: Cardinal; const B: BigInteger): BigInteger;
|
|
|
+ class operator IntDivide(const A: Cardinal; const B: BigInteger): BigInteger;
|
|
|
+ class operator Modulus(const A: Cardinal; const B: BigInteger): Cardinal;
|
|
|
+ class function DivRem(const Dividend: Cardinal; const Divisor: BigInteger;
|
|
|
+ var Remainder: Cardinal): BigInteger; overload; static;
|
|
|
+
|
|
|
+// arithmetic operations on BigInteger & Integer
|
|
|
+ class operator Add(const A: BigInteger; const B: Integer): BigInteger;
|
|
|
+ class operator Subtract(const A: BigInteger; const B: Integer): BigInteger;
|
|
|
+ class operator Multiply(const A: BigInteger; const B: Integer): BigInteger;
|
|
|
+ class operator IntDivide(const A: BigInteger; const B: Integer): BigInteger;
|
|
|
+ class operator Modulus(const A: BigInteger; const B: Integer): Integer;
|
|
|
+ class function DivRem(const Dividend: BigInteger; const Divisor: Integer;
|
|
|
+ var Remainder: Integer): BigInteger; overload; static;
|
|
|
+
|
|
|
+// arithmetic operations on Integer & BigInteger
|
|
|
+ class operator Add(const A: Integer; const B: BigInteger): BigInteger;
|
|
|
+ class operator Subtract(const A: Integer; const B: BigInteger): BigInteger;
|
|
|
+ class operator Multiply(const A: Integer; const B: BigInteger): BigInteger;
|
|
|
+ class operator IntDivide(const A: Integer; const B: BigInteger): Integer;
|
|
|
+ class operator Modulus(const A: Integer; const B: BigInteger): Integer;
|
|
|
+ class function DivRem(const Dividend: Integer; const Divisor: BigInteger;
|
|
|
+ var Remainder: Integer): Integer; overload; static;
|
|
|
+ end;
|
|
|
+
|
|
|
+type
|
|
|
+ EBigNumberError = class(Exception)
|
|
|
+ private
|
|
|
+ FCode: TF_RESULT;
|
|
|
+ public
|
|
|
+ constructor Create(ACode: TF_RESULT; const Msg: string = '');
|
|
|
+ property Code: TF_RESULT read FCode;
|
|
|
+ end;
|
|
|
+
|
|
|
+procedure BigNumberError(ACode: TF_RESULT; const Msg: string = '');
|
|
|
+
|
|
|
+implementation
|
|
|
+
|
|
|
+const
|
|
|
+ NumericsVersion = 55;
|
|
|
+
|
|
|
+type
|
|
|
+ TGetNumericsVersion = function(var Version: LongWord): TF_RESULT; stdcall;
|
|
|
+ TBigNumberFromUInt32 = function(var A: IBigNumber; Value: Cardinal): TF_RESULT; stdcall;
|
|
|
+ TBigNumberFromUInt64 = function(var A: IBigNumber; Value: UInt64): TF_RESULT; stdcall;
|
|
|
+ TBigNumberFromInt32 = function(var A: IBigNumber; Value: Integer): TF_RESULT; stdcall;
|
|
|
+ TBigNumberFromInt64 = function(var A: IBigNumber; Value: Int64): TF_RESULT; stdcall;
|
|
|
+ TBigNumberFromPChar = function(var A: IBigNumber; P: PByte; L: Integer;
|
|
|
+ CharSize: Integer; AllowNegative: Boolean; TwoCompl: Boolean): TF_RESULT; stdcall;
|
|
|
+ TBigNumberFromPByte = function(var A: IBigNumber;
|
|
|
+ P: PByte; L: Integer; AllowNegative: Boolean): TF_RESULT; stdcall;
|
|
|
+
|
|
|
+var
|
|
|
+ GetNumericsVersion: TGetNumericsVersion;
|
|
|
+ BigNumberFromLimb: TBigNumberFromUInt32;
|
|
|
+ BigNumberFromDblLimb: TBigNumberFromUInt64;
|
|
|
+ BigNumberFromIntLimb: TBigNumberFromInt32;
|
|
|
+ BigNumberFromDblIntLimb: TBigNumberFromInt64;
|
|
|
+ BigNumberFromPChar: TBigNumberFromPChar;
|
|
|
+ BigNumberFromPByte: TBigNumberFromPByte;
|
|
|
+
|
|
|
+{ EBigNumberError }
|
|
|
+
|
|
|
+constructor EBigNumberError.Create(ACode: TF_RESULT; const Msg: string);
|
|
|
+begin
|
|
|
+ if Msg = '' then
|
|
|
+ inherited Create(Format('Big Number Error 0x%.8x', [ACode]))
|
|
|
+ else
|
|
|
+ inherited Create(Msg);
|
|
|
+ FCode:= ACode;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure BigNumberError(ACode: TF_RESULT; const Msg: string);
|
|
|
+begin
|
|
|
+ raise EBigNumberError.Create(ACode, Msg);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure HResCheck(Value: TF_RESULT); inline;
|
|
|
+begin
|
|
|
+ if Value <> S_OK then
|
|
|
+ BigNumberError(Value);
|
|
|
+end;
|
|
|
+
|
|
|
+{ BigCardinal }
|
|
|
+
|
|
|
+function BigCardinal.ToString: string;
|
|
|
+var
|
|
|
+ BytesUsed: Integer;
|
|
|
+ L: Integer;
|
|
|
+ P, P1: PByte;
|
|
|
+ I: Integer;
|
|
|
+
|
|
|
+begin
|
|
|
+ BytesUsed:= FNumber.GetSize;
|
|
|
+// log(256) approximated from above by 41/17
|
|
|
+ L:= (BytesUsed * 41) div 17 + 1;
|
|
|
+ GetMem(P, L);
|
|
|
+ try
|
|
|
+ HResCheck(FNumber.ToDec(P, L));
|
|
|
+ SetLength(Result, L);
|
|
|
+ P1:= P;
|
|
|
+ for I:= 1 to L do begin
|
|
|
+ Result[I]:= Char(P1^);
|
|
|
+ Inc(P1);
|
|
|
+ end;
|
|
|
+ finally
|
|
|
+ FreeMem(P);
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function BigCardinal.ToHexString(Digits: Integer; const Prefix: string;
|
|
|
+ TwoCompl: Boolean): string;
|
|
|
+
|
|
|
+var
|
|
|
+ L: Integer;
|
|
|
+ P, P1: PByte;
|
|
|
+ HR: TF_RESULT;
|
|
|
+ I: Integer;
|
|
|
+
|
|
|
+begin
|
|
|
+ Result:= '';
|
|
|
+ HR:= FNumber.ToHex(nil, L, TwoCompl);
|
|
|
+ if HR = TF_E_INVALIDARG then begin
|
|
|
+ GetMem(P, L);
|
|
|
+ try
|
|
|
+ HResCheck(FNumber.ToHex(P, L, TwoCompl));
|
|
|
+ if Digits < L then Digits:= L;
|
|
|
+ Inc(Digits, Length(Prefix));
|
|
|
+ SetLength(Result, Digits);
|
|
|
+ Move(Pointer(Prefix)^, Pointer(Result)^, Length(Prefix) * SizeOf(Char));
|
|
|
+ P1:= P;
|
|
|
+ I:= Length(Prefix);
|
|
|
+ while I + L < Digits do begin
|
|
|
+ Inc(I);
|
|
|
+ Result[I]:= '0';
|
|
|
+ end;
|
|
|
+ while I < Digits do begin
|
|
|
+ Inc(I);
|
|
|
+ Result[I]:= Char(P1^);
|
|
|
+ Inc(P1);
|
|
|
+ end;
|
|
|
+ finally
|
|
|
+ FreeMem(P);
|
|
|
+ end;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ BigNumberError(HR);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigCardinal.ToBytes: TBytes;
|
|
|
+var
|
|
|
+ HR: TF_RESULT;
|
|
|
+ L: Cardinal;
|
|
|
+
|
|
|
+begin
|
|
|
+ L:= 0;
|
|
|
+ HR:= FNumber.ToPByte(nil, L);
|
|
|
+ if (HR = TF_E_INVALIDARG) and (L > 0) then begin
|
|
|
+ SetLength(Result, L);
|
|
|
+ HR:= FNumber.ToPByte(Pointer(Result), L);
|
|
|
+ end;
|
|
|
+ HResCheck(HR);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigCardinal.TryParse(const S: string; TwoCompl: Boolean): Boolean;
|
|
|
+begin
|
|
|
+ Result:= BigNumberFromPChar(FNumber, Pointer(S), Length(S),
|
|
|
+ SizeOf(Char), False, TwoCompl) = TF_S_OK;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure BigCardinal.Free;
|
|
|
+begin
|
|
|
+ FNumber:= nil;
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigCardinal.Compare(const A, B: BigCardinal): Integer;
|
|
|
+begin
|
|
|
+ Result:= A.FNumber.CompareNumberU(B.FNumber);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigCardinal.CompareTo(const B: BigCardinal): Integer;
|
|
|
+begin
|
|
|
+ Result:= Compare(Self, B);
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigCardinal.Pow(const Base: BigCardinal; Value: Cardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(Base.FNumber.PowU(Value, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigCardinal.DivRem(const Dividend, Divisor: BigCardinal;
|
|
|
+ var Remainder: BigCardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(Dividend.FNumber.DivRemNumberU(Divisor.FNumber,
|
|
|
+ Result.FNumber, Remainder.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Explicit(const Value: BigCardinal): Cardinal;
|
|
|
+begin
|
|
|
+ HResCheck(Value.FNumber.ToLimb(Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Explicit(const Value: BigCardinal): Integer;
|
|
|
+begin
|
|
|
+ HResCheck(Value.FNumber.ToIntLimb(Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Explicit(const Value: BigCardinal): UInt64;
|
|
|
+begin
|
|
|
+ HResCheck(Value.FNumber.ToDblLimb(Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Explicit(const Value: BigCardinal): Int64;
|
|
|
+begin
|
|
|
+ HResCheck(Value.FNumber.ToDblIntLimb(Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Implicit(const Value: Cardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(BigNumberFromLimb(Result.FNumber, Value));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Implicit(const Value: UInt64): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(BigNumberFromDblLimb(Result.FNumber, Value));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Explicit(const Value: Integer): BigCardinal;
|
|
|
+begin
|
|
|
+ if Value < 0 then
|
|
|
+ BigNumberError(TF_E_INVALIDARG)
|
|
|
+ else
|
|
|
+ HResCheck(BigNumberFromIntLimb(Result.FNumber, Value));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Explicit(const Value: Int64): BigCardinal;
|
|
|
+begin
|
|
|
+ if Value < 0 then
|
|
|
+ BigNumberError(TF_E_INVALIDARG)
|
|
|
+ else
|
|
|
+ HResCheck(BigNumberFromDblIntLimb(Result.FNumber, Value));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Explicit(const Value: TBytes): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(BigNumberFromPByte(Result.FNumber,
|
|
|
+ Pointer(Value), Length(Value), False));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Explicit(const Value: string): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(BigNumberFromPChar(Result.FNumber, Pointer(Value), Length(Value),
|
|
|
+ SizeOf(Char), False, False));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Equal(const A, B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.NotEqual(const A, B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThan(const A, B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThanOrEqual(const A, B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThan(const A, B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThanOrEqual(const A, B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Add(const A, B: BigCardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.AddNumberU(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Subtract(const A, B: BigCardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.SubNumberU(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Multiply(const A, B: BigCardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.MulNumberU(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.IntDivide(const A, B: BigCardinal): BigCardinal;
|
|
|
+var
|
|
|
+ Remainder: IBigNumber;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.DivRemNumberU(B.FNumber, Result.FNumber, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Modulus(const A, B: BigCardinal): BigCardinal;
|
|
|
+var
|
|
|
+ Quotient: IBigNumber;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.DivRemNumberU(B.FNumber, Quotient, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+
|
|
|
+class operator BigCardinal.LeftShift(const A: BigCardinal; Shift: Cardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.ShlNumber(Shift, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.RightShift(const A: BigCardinal; Shift: Cardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.ShrNumber(Shift, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.BitwiseAnd(const A, B: BigCardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.AndNumberU(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.BitwiseOr(const A, B: BigCardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.OrNumberU(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+function BigCardinal.CompareToCard(const B: Cardinal): Integer;
|
|
|
+begin
|
|
|
+ Result:= FNumber.CompareToLimbU(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigCardinal.CompareToInt(const B: Integer): Integer;
|
|
|
+begin
|
|
|
+ Result:= FNumber.CompareToIntLimbU(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigCardinal.CompareTo(const B: Cardinal): Integer;
|
|
|
+begin
|
|
|
+ Result:= CompareToCard(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigCardinal.CompareTo(const B: Integer): Integer;
|
|
|
+begin
|
|
|
+ Result:= CompareToInt(B);
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Equal(const A: BigCardinal; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Equal(const A: Cardinal; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Equal(const A: BigCardinal; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Equal(const A: Integer; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.NotEqual(const A: BigCardinal; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.NotEqual(const A: Cardinal; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.NotEqual(const A: BigCardinal; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.NotEqual(const A: Integer; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThan(const A: BigCardinal; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThan(const A: Cardinal; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThan(const A: BigCardinal; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThan(const A: Integer; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThanOrEqual(const A: BigCardinal; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThanOrEqual(const A: Cardinal; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThanOrEqual(const A: BigCardinal; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThanOrEqual(const A: Integer; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThan(const A: BigCardinal; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThan(const A: Cardinal; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThan(const A: BigCardinal; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThan(const A: Integer; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThanOrEqual(const A: BigCardinal; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThanOrEqual(const A: Cardinal; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThanOrEqual(const A: BigCardinal; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThanOrEqual(const A: Integer; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+{--- Comparison with 64-bit integers ---}
|
|
|
+
|
|
|
+function BigCardinal.CompareToUInt64(const B: UInt64): Integer;
|
|
|
+begin
|
|
|
+ Result:= FNumber.CompareToDblLimbU(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigCardinal.CompareToInt64(const B: Int64): Integer;
|
|
|
+begin
|
|
|
+ Result:= FNumber.CompareToDblIntLimbU(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigCardinal.CompareTo(const B: UInt64): Integer;
|
|
|
+begin
|
|
|
+ Result:= CompareToUInt64(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigCardinal.CompareTo(const B: Int64): Integer;
|
|
|
+begin
|
|
|
+ Result:= CompareToInt64(B);
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Equal(const A: BigCardinal; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToUInt64(B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Equal(const A: UInt64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToUInt64(A) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Equal(const A: BigCardinal; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt64(B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Equal(const A: Int64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt64(A) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.NotEqual(const A: BigCardinal; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToUInt64(B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.NotEqual(const A: UInt64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToUInt64(A) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.NotEqual(const A: BigCardinal; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt64(B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.NotEqual(const A: Int64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt64(A) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThan(const A: BigCardinal; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToUInt64(B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThan(const A: UInt64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToUInt64(A) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThan(const A: BigCardinal; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt64(B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThan(const A: Int64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt64(A) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThanOrEqual(const A: BigCardinal; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToUInt64(B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThanOrEqual(const A: UInt64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToUInt64(A) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThanOrEqual(const A: BigCardinal; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt64(B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.GreaterThanOrEqual(const A: Int64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt64(A) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThan(const A: BigCardinal; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToUInt64(B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThan(const A: UInt64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToUInt64(A) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThan(const A: BigCardinal; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt64(B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThan(const A: Int64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt64(A) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThanOrEqual(const A: BigCardinal; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToUInt64(B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThanOrEqual(const A: UInt64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToUInt64(A) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThanOrEqual(const A: BigCardinal; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt64(B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.LessThanOrEqual(const A: Int64; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt64(A) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+class operator BigCardinal.Add(const A: BigCardinal; const B: Cardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.AddLimbU(B, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Add(const A: Cardinal; const B: BigCardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.AddLimbU(A, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Subtract(const A: BigCardinal; const B: Cardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.SubLimbU(B, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Subtract(const A: Cardinal; const B: BigCardinal): Cardinal;
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.SubLimbU2(A, Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Multiply(const A: BigCardinal; const B: Cardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.MulLimbU(B, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Multiply(const A: Cardinal; const B: BigCardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.MulLimbU(A, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+
|
|
|
+class function BigCardinal.DivRem(const Dividend: BigCardinal;
|
|
|
+ Divisor: Cardinal; var Remainder: Cardinal): BigCardinal;
|
|
|
+begin
|
|
|
+ HResCheck(Dividend.FNumber.DivRemLimbU(Divisor, Result.FNumber, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigCardinal.DivRem(const Dividend: Cardinal;
|
|
|
+ Divisor: BigCardinal; var Remainder: Cardinal): Cardinal;
|
|
|
+begin
|
|
|
+ HResCheck(Divisor.FNumber.DivRemLimbU2(Dividend, Result, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.IntDivide(const A: BigCardinal; const B: Cardinal): BigCardinal;
|
|
|
+var
|
|
|
+ Remainder: Cardinal;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.DivRemLimbU(B, Result.FNumber, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.IntDivide(const A: Cardinal; const B: BigCardinal): Cardinal;
|
|
|
+var
|
|
|
+ Remainder: Cardinal;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.DivRemLimbU2(A, Result, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigCardinal.Modulus(const A: BigCardinal; const B: Cardinal): Cardinal;
|
|
|
+var
|
|
|
+ Quotient: IBigNumber;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.DivRemLimbU(B, Quotient, Result));
|
|
|
+end;
|
|
|
+
|
|
|
+
|
|
|
+class operator BigCardinal.Modulus(const A: Cardinal; const B: BigCardinal): Cardinal;
|
|
|
+var
|
|
|
+ Quotient: Cardinal;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.DivRemLimbU2(A, Quotient, Result));
|
|
|
+end;
|
|
|
+
|
|
|
+{ -------------------------- BigInteger -------------------------- }
|
|
|
+
|
|
|
+function BigInteger.GetSign: Integer;
|
|
|
+begin
|
|
|
+ Result:= FNumber.GetSign;
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.ToString: string;
|
|
|
+var
|
|
|
+ BytesUsed: Integer;
|
|
|
+ L: Integer;
|
|
|
+ P, P1: PByte;
|
|
|
+ I: Integer;
|
|
|
+ IsMinus: Boolean;
|
|
|
+
|
|
|
+begin
|
|
|
+ BytesUsed:= FNumber.GetSize;
|
|
|
+// log(256) approximated from above by 41/17
|
|
|
+ L:= (BytesUsed * 41) div 17 + 1;
|
|
|
+ GetMem(P, L);
|
|
|
+ try
|
|
|
+ HResCheck(FNumber.ToDec(P, L));
|
|
|
+ IsMinus:= GetSign < 0;
|
|
|
+ if IsMinus then Inc(L);
|
|
|
+ SetLength(Result, L);
|
|
|
+ I:= 1;
|
|
|
+ if IsMinus then begin
|
|
|
+ Result[1]:= '-';
|
|
|
+ Inc(I);
|
|
|
+ end;
|
|
|
+ P1:= P;
|
|
|
+ while I <= L do begin
|
|
|
+ Result[I]:= Char(P1^);
|
|
|
+ Inc(P1);
|
|
|
+ Inc(I);
|
|
|
+ end;
|
|
|
+ finally
|
|
|
+ FreeMem(P);
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.ToHexString(Digits: Integer; const Prefix: string;
|
|
|
+ TwoCompl: Boolean): string;
|
|
|
+const
|
|
|
+ ASCII_8 = 56; // Ord('8')
|
|
|
+
|
|
|
+var
|
|
|
+ L: Integer;
|
|
|
+ P, P1: PByte;
|
|
|
+ HR: TF_RESULT;
|
|
|
+ Filler: Char;
|
|
|
+ I: Integer;
|
|
|
+
|
|
|
+begin
|
|
|
+ Result:= '';
|
|
|
+ HR:= FNumber.ToHex(nil, L, TwoCompl);
|
|
|
+ if HR = TF_E_INVALIDARG then begin
|
|
|
+ GetMem(P, L);
|
|
|
+ try
|
|
|
+ HResCheck(FNumber.ToHex(P, L, TwoCompl));
|
|
|
+ if Digits < L then Digits:= L;
|
|
|
+ I:= 1;
|
|
|
+ if (FNumber.GetSign < 0) and not TwoCompl then begin
|
|
|
+ Inc(I);
|
|
|
+ SetLength(Result, Digits + Length(Prefix) + 1);
|
|
|
+ Result[1]:= '-';
|
|
|
+ end
|
|
|
+ else
|
|
|
+ SetLength(Result, Digits + Length(Prefix));
|
|
|
+ Move(Pointer(Prefix)^, Result[I], Length(Prefix) * SizeOf(Char));
|
|
|
+ Inc(I, Length(Prefix));
|
|
|
+ if Digits > L then begin
|
|
|
+ if TwoCompl and (P[L] >= ASCII_8) then Filler:= 'F'
|
|
|
+ else Filler:= '0';
|
|
|
+ while I + L <= Length(Result) do begin
|
|
|
+ Result[I]:= Filler;
|
|
|
+ Inc(I);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ P1:= P;
|
|
|
+ while I <= Length(Result) do begin
|
|
|
+ Result[I]:= Char(P1^);
|
|
|
+ Inc(I);
|
|
|
+ Inc(P1);
|
|
|
+ end;
|
|
|
+ finally
|
|
|
+ FreeMem(P);
|
|
|
+ end;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ BigNumberError(HR);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.ToBytes: TBytes;
|
|
|
+var
|
|
|
+ HR: TF_RESULT;
|
|
|
+ L: Cardinal;
|
|
|
+
|
|
|
+begin
|
|
|
+ Result:= nil;
|
|
|
+ HR:= FNumber.ToPByte(nil, L);
|
|
|
+ if (HR = TF_E_INVALIDARG) and (L > 0) then begin
|
|
|
+ SetLength(Result, L);
|
|
|
+ HR:= FNumber.ToPByte(Pointer(Result), L);
|
|
|
+ end;
|
|
|
+ HResCheck(HR);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.TryParse(const S: string; TwoCompl: Boolean): Boolean;
|
|
|
+begin
|
|
|
+ Result:= BigNumberFromPChar(FNumber, Pointer(S), Length(S),
|
|
|
+ SizeOf(Char), True, TwoCompl) = TF_S_OK;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure BigInteger.Free;
|
|
|
+begin
|
|
|
+ FNumber:= nil;
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.Compare(const A, B: BigInteger): Integer;
|
|
|
+begin
|
|
|
+ Result:= A.FNumber.CompareNumber(B.FNumber);
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.Compare(const A: BigInteger; const B: BigCardinal): Integer;
|
|
|
+begin
|
|
|
+ Result:= A.FNumber.CompareNumber(B.FNumber);
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.Compare(const A: BigCardinal; const B: BigInteger): Integer;
|
|
|
+begin
|
|
|
+ Result:= A.FNumber.CompareNumber(B.FNumber);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.CompareTo(const B: BigInteger): Integer;
|
|
|
+begin
|
|
|
+ Result:= Compare(Self, B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.CompareTo(const B: BigCardinal): Integer;
|
|
|
+begin
|
|
|
+ Result:= Compare(Self, B);
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.Abs(const A: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.AbsNumber(Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.Pow(const Base: BigInteger; Value: Cardinal): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(Base.FNumber.Pow(Value, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.DivRem(const Dividend, Divisor: BigInteger;
|
|
|
+ var Remainder: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(Dividend.FNumber.DivRemNumber(Divisor.FNumber,
|
|
|
+ Result.FNumber, Remainder.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.Sqrt(A: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.SqrtNumber(Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.GCD(A, B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.GCD(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.EGCD(A, B: BigInteger; var X, Y: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.EGCD(B.FNumber, Result.FNumber, X.FNumber, Y.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.ModPow(const BaseValue, ExpValue,
|
|
|
+ Modulo: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(BaseValue.FNumber.ModPow(ExpValue.FNumber,
|
|
|
+ Modulo.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.ModInverse(A, Modulo: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.ModInverse(Modulo.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Implicit(const Value: BigCardinal): BigInteger;
|
|
|
+begin
|
|
|
+ Result.FNumber:= Value.FNumber;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Explicit(const Value: BigInteger): BigCardinal;
|
|
|
+begin
|
|
|
+ if (Value.FNumber.GetSign < 0) then
|
|
|
+ BigNumberError(TF_E_INVALIDARG);
|
|
|
+ Result.FNumber:= Value.FNumber;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Explicit(const Value: BigInteger): Cardinal;
|
|
|
+begin
|
|
|
+ HResCheck(Value.FNumber.ToLimb(Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Explicit(const Value: BigInteger): UInt64;
|
|
|
+begin
|
|
|
+ HResCheck(Value.FNumber.ToDblLimb(Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Explicit(const Value: BigInteger): Integer;
|
|
|
+begin
|
|
|
+ HResCheck(Value.FNumber.ToIntLimb(Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Explicit(const Value: BigInteger): Int64;
|
|
|
+begin
|
|
|
+ HResCheck(Value.FNumber.ToDblIntLimb(Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Implicit(const Value: UInt32): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(BigNumberFromLimb(Result.FNumber, Value));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Implicit(const Value: UInt64): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(BigNumberFromDblLimb(Result.FNumber, Value));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Implicit(const Value: Int32): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(BigNumberFromIntLimb(Result.FNumber, Value));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Implicit(const Value: Int64): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(BigNumberFromDblIntLimb(Result.FNumber, Value));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Explicit(const Value: TBytes): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(BigNumberFromPByte(Result.FNumber,
|
|
|
+ Pointer(Value), Length(Value), True));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Explicit(const Value: string): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(BigNumberFromPChar(Result.FNumber, Pointer(Value), Length(Value),
|
|
|
+ SizeOf(Char), True, False));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Equal(const A, B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Equal(const A: BigCardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Equal(const A: BigInteger; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.NotEqual(const A, B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.NotEqual(const A: BigCardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.NotEqual(const A: BigInteger; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThan(const A, B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThan(const A: BigInteger; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThan(const A: BigCardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThanOrEqual(const A, B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThanOrEqual(const A: BigInteger; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThanOrEqual(const A: BigCardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThan(const A, B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThan(const A: BigInteger; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThan(const A: BigCardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThanOrEqual(const A, B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThanOrEqual(const A: BigInteger; const B: BigCardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThanOrEqual(const A: BigCardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= Compare(A, B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Add(const A, B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.AddNumber(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Subtract(const A, B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.SubNumber(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Multiply(const A, B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.MulNumber(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.IntDivide(const A, B: BigInteger): BigInteger;
|
|
|
+var
|
|
|
+ Remainder: IBigNumber;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.DivRemNumber(B.FNumber, Result.FNumber, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Modulus(const A, B: BigInteger): BigInteger;
|
|
|
+var
|
|
|
+ Quotient: IBigNumber;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.DivRemNumber(B.FNumber, Quotient, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LeftShift(const A: BigInteger; Shift: Cardinal): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.ShlNumber(Shift, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.RightShift(const A: BigInteger; Shift: Cardinal): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.ShrNumber(Shift, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.BitwiseAnd(const A, B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.AndNumber(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.BitwiseOr(const A, B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.OrNumber(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.BitwiseXor(const A, B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.XorNumber(B.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.CompareToCard(const B: Cardinal): Integer;
|
|
|
+begin
|
|
|
+ Result:= FNumber.CompareToLimb(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.CompareToInt(const B: Integer): Integer;
|
|
|
+begin
|
|
|
+ Result:= FNumber.CompareToIntLimb(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.CompareTo(const B: Cardinal): Integer;
|
|
|
+begin
|
|
|
+ Result:= CompareToCard(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.CompareTo(const B: Integer): Integer;
|
|
|
+begin
|
|
|
+ Result:= CompareToInt(B);
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Equal(const A: BigInteger; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Equal(const A: Cardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Equal(const A: BigInteger; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Equal(const A: Integer; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.NotEqual(const A: BigInteger; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.NotEqual(const A: Cardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.NotEqual(const A: BigInteger; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.NotEqual(const A: Integer; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThan(const A: BigInteger; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThan(const A: Cardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThan(const A: BigInteger; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThan(const A: Integer; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThanOrEqual(const A: BigInteger; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThanOrEqual(const A: Cardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThanOrEqual(const A: BigInteger; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThanOrEqual(const A: Integer; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThan(const A: BigInteger; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThan(const A: Cardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThan(const A: BigInteger; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThan(const A: Integer; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThanOrEqual(const A: BigInteger; const B: Cardinal): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToCard(B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThanOrEqual(const A: Cardinal; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToCard(A) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThanOrEqual(const A: BigInteger; const B: Integer): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToInt(B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThanOrEqual(const A: Integer; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToInt(A) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+
|
|
|
+function BigInteger.CompareToDoubleUInt(const B: UInt64): Integer;
|
|
|
+begin
|
|
|
+ Result:= FNumber.CompareToDblLimb(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.CompareToDoubleInt(const B: Int64): Integer;
|
|
|
+begin
|
|
|
+ Result:= FNumber.CompareToDblIntLimb(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.CompareTo(const B: UInt64): Integer;
|
|
|
+begin
|
|
|
+ Result:= CompareToDoubleUInt(B);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigInteger.CompareTo(const B: Int64): Integer;
|
|
|
+begin
|
|
|
+ Result:= CompareToDoubleInt(B);
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Equal(const A: BigInteger; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleUInt(B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Equal(const A: UInt64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleUInt(A) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Equal(const A: BigInteger; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleInt(B) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Equal(const A: Int64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleInt(A) = 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.NotEqual(const A: BigInteger; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleUInt(B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.NotEqual(const A: UInt64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleUInt(A) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.NotEqual(const A: BigInteger; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleInt(B) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.NotEqual(const A: Int64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleInt(A) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThan(const A: BigInteger; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleUInt(B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThan(const A: UInt64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleUInt(A) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThan(const A: BigInteger; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleInt(B) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThan(const A: Int64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleInt(A) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThanOrEqual(const A: BigInteger; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleUInt(B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThanOrEqual(const A: UInt64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleUInt(A) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThanOrEqual(const A: BigInteger; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleInt(B) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.GreaterThanOrEqual(const A: Int64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleInt(A) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThan(const A: BigInteger; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleUInt(B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThan(const A: UInt64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleUInt(A) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThan(const A: BigInteger; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleInt(B) < 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThan(const A: Int64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleInt(A) > 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThanOrEqual(const A: BigInteger; const B: UInt64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleUInt(B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThanOrEqual(const A: UInt64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleUInt(A) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThanOrEqual(const A: BigInteger; const B: Int64): Boolean;
|
|
|
+begin
|
|
|
+ Result:= A.CompareToDoubleInt(B) <= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.LessThanOrEqual(const A: Int64; const B: BigInteger): Boolean;
|
|
|
+begin
|
|
|
+ Result:= B.CompareToDoubleInt(A) >= 0;
|
|
|
+end;
|
|
|
+
|
|
|
+// -- arithmetic operations on BigInteger & Cardinal --
|
|
|
+
|
|
|
+class operator BigInteger.Add(const A: BigInteger; const B: Cardinal): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.AddLimb(B, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Subtract(const A: BigInteger; const B: Cardinal): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.SubLimb(B, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Multiply(const A: BigInteger; const B: Cardinal): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.MulLimb(B, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.IntDivide(const A: BigInteger; const B: Cardinal): BigInteger;
|
|
|
+var
|
|
|
+ Remainder: BigInteger;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.DivRemLimb(B, Result.FNumber, Remainder.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Modulus(const A: BigInteger; const B: Cardinal): BigInteger;
|
|
|
+var
|
|
|
+ Quotient: BigInteger;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.DivRemLimb(B, Quotient.FNumber, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.DivRem(const Dividend: BigInteger;
|
|
|
+ const Divisor: Cardinal; var Remainder: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(Dividend.FNumber.DivRemLimb(Divisor, Result.FNumber, Remainder.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+// -- arithmetic operations on Cardinal & BigInteger --
|
|
|
+
|
|
|
+class operator BigInteger.Add(const A: Cardinal; const B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.AddLimb(A, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Subtract(const A: Cardinal; const B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.SubLimb2(A, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Multiply(const A: Cardinal; const B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.MulLimb(A, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.IntDivide(const A: Cardinal; const B: BigInteger): BigInteger;
|
|
|
+var
|
|
|
+ Remainder: Cardinal;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.DivRemLimb2(A, Result.FNumber, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Modulus(const A: Cardinal; const B: BigInteger): Cardinal;
|
|
|
+var
|
|
|
+ Quotient: BigInteger;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.DivRemLimb2(A, Quotient.FNumber, Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.DivRem(const Dividend: Cardinal;
|
|
|
+ const Divisor: BigInteger; var Remainder: Cardinal): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(Divisor.FNumber.DivRemLimb2(Dividend, Result.FNumber, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+// -- arithmetic operations on BigInteger & Integer --
|
|
|
+
|
|
|
+class operator BigInteger.Add(const A: BigInteger; const B: Integer): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.AddIntLimb(B, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Subtract(const A: BigInteger; const B: Integer): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.SubIntLimb(B, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Multiply(const A: BigInteger; const B: Integer): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.MulIntLimb(B, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.IntDivide(const A: BigInteger; const B: Integer): BigInteger;
|
|
|
+var
|
|
|
+ Remainder: Integer;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.DivRemIntLimb(B, Result.FNumber, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Modulus(const A: BigInteger; const B: Integer): Integer;
|
|
|
+var
|
|
|
+ Quotient: BigInteger;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(A.FNumber.DivRemIntLimb(B, Quotient.FNumber, Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.DivRem(const Dividend: BigInteger;
|
|
|
+ const Divisor: Integer; var Remainder: Integer): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(Dividend.FNumber.DivRemIntLimb(Divisor, Result.FNumber, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+// -- arithmetic operations on Integer & BigInteger --
|
|
|
+
|
|
|
+class operator BigInteger.Add(const A: Integer; const B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.AddIntLimb(A, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Subtract(const A: Integer; const B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.SubIntLimb2(A, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Multiply(const A: Integer; const B: BigInteger): BigInteger;
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.MulIntLimb(A, Result.FNumber));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.IntDivide(const A: Integer; const B: BigInteger): Integer;
|
|
|
+var
|
|
|
+ Remainder: Integer;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.DivRemIntLimb2(A, Result, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+class operator BigInteger.Modulus(const A: Integer; const B: BigInteger): Integer;
|
|
|
+var
|
|
|
+ Quotient: Integer;
|
|
|
+
|
|
|
+begin
|
|
|
+ HResCheck(B.FNumber.DivRemIntLimb2(A, Quotient, Result));
|
|
|
+end;
|
|
|
+
|
|
|
+class function BigInteger.DivRem(const Dividend: Integer;
|
|
|
+ const Divisor: BigInteger; var Remainder: Integer): Integer;
|
|
|
+begin
|
|
|
+ HResCheck(Divisor.FNumber.DivRemIntLimb2(Dividend, Result, Remainder));
|
|
|
+end;
|
|
|
+
|
|
|
+
|
|
|
+// ------------------------ DLL load stuff ---------------------------- //
|
|
|
+
|
|
|
+const
|
|
|
+{$IFDEF WIN64}
|
|
|
+ LibName = 'numerics64.dll';
|
|
|
+{$ELSE}
|
|
|
+ LibName = 'numerics32.dll';
|
|
|
+{$ENDIF}
|
|
|
+
|
|
|
+function GetNumericsVersionError(var Version: LongWord): TF_RESULT; stdcall;
|
|
|
+begin
|
|
|
+ Result:= TF_E_LOADERROR;
|
|
|
+end;
|
|
|
+
|
|
|
+function BigNumberFrom32Error(var A: IBigNumber; Value: UInt32): TF_RESULT; stdcall;
|
|
|
+begin
|
|
|
+ Result:= TF_E_LOADERROR;
|
|
|
+end;
|
|
|
+
|
|
|
+function BigNumberFrom64Error(var A: IBigNumber; Value: UInt64): TF_RESULT; stdcall;
|
|
|
+begin
|
|
|
+ Result:= TF_E_LOADERROR;
|
|
|
+end;
|
|
|
+
|
|
|
+function BigNumberFromPCharError(var A: IBigNumber; P: PByte; L: Integer;
|
|
|
+ CharSize: Integer; AllowNegative: Boolean; TwoCompl: Boolean): TF_RESULT; stdcall;
|
|
|
+begin
|
|
|
+ Result:= TF_E_LOADERROR;
|
|
|
+end;
|
|
|
+
|
|
|
+function BigNumberFromPByteError(var A: IBigNumber;
|
|
|
+ P: PByte; L: Cardinal; AllowNegative: Boolean): TF_RESULT; stdcall;
|
|
|
+begin
|
|
|
+ Result:= TF_E_LOADERROR;
|
|
|
+end;
|
|
|
+
|
|
|
+var
|
|
|
+ LibLoaded: Boolean = False;
|
|
|
+
|
|
|
+function BigNumberFromLimbStub(var A: IBigNumber; Value: UInt32): TF_RESULT; stdcall;
|
|
|
+begin
|
|
|
+// LoadNumerics(LibName);
|
|
|
+ Result:= BigNumberFromLimb(A, Value);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigNumberFromDblLimbStub(var A: IBigNumber; Value: UInt64): TF_RESULT; stdcall;
|
|
|
+begin
|
|
|
+// LoadNumerics(LibName);
|
|
|
+ Result:= BigNumberFromDblLimb(A, Value);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigNumberFromIntLimbStub(var A: IBigNumber; Value: Int32): TF_RESULT; stdcall;
|
|
|
+begin
|
|
|
+// LoadNumerics(LibName);
|
|
|
+ Result:= BigNumberFromIntLimb(A, Value);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigNumberFromDblIntLimbStub(var A: IBigNumber; Value: Int64): TF_RESULT; stdcall;
|
|
|
+begin
|
|
|
+// LoadNumerics(LibName);
|
|
|
+ Result:= BigNumberFromDblIntLimb(A, Value);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigNumberFromPCharStub(var A: IBigNumber; P: PByte; L: Integer;
|
|
|
+ CharSize: Integer; AllowNegative: Boolean; TwoCompl: Boolean): TF_RESULT; stdcall;
|
|
|
+begin
|
|
|
+// LoadNumerics(LibName);
|
|
|
+ Result:= BigNumberFromPCharStub(A, P, L, CharSize, AllowNegative, TwoCompl);
|
|
|
+end;
|
|
|
+
|
|
|
+function BigNumberFromPByteStub(var A: IBigNumber;
|
|
|
+ P: PByte; L: Cardinal; AllowNegative: Boolean): TF_RESULT; stdcall;
|
|
|
+begin
|
|
|
+// LoadNumerics(LibName);
|
|
|
+ Result:= BigNumberFromPByteStub(A, P, L, AllowNegative);
|
|
|
+end;
|
|
|
+
|
|
|
+initialization
|
|
|
+ @BigNumberFromLimb:= @BigNumberFromLimbStub;
|
|
|
+ @BigNumberFromDblLimb:= @BigNumberFromDblLimbStub;
|
|
|
+ @BigNumberFromIntLimb:= @BigNumberFromIntLimbStub;
|
|
|
+ @BigNumberFromDblIntLimb:= @BigNumberFromDblIntLimbStub;
|
|
|
+ @BigNumberFromPChar:= @BigNumberFromPCharStub;
|
|
|
+ @BigNumberFromPByte:= @BigNumberFromPByteStub;
|
|
|
+
|
|
|
+end.
|