mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 14:48:14 +02:00
2042 lines
70 KiB
ObjectPascal
2042 lines
70 KiB
ObjectPascal
{ %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 tw26226;
|
|
|
|
{$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.
|