fpc/tests/webtbs/tw26226.pp
Jonas Maebe 19c310f5d3 * fixed unit name
git-svn-id: trunk@27829 -
2014-05-30 07:25:04 +00:00

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.