Переглянути джерело

+ test for mantis #26226 (already works with FPC 2.7.1)

git-svn-id: trunk@27823 -
Jonas Maebe 11 роки тому
батько
коміт
03ef4b6477
2 змінених файлів з 2042 додано та 0 видалено
  1. 1 0
      .gitattributes
  2. 2041 0
      tests/webtbs/tw26226.pp

+ 1 - 0
.gitattributes

@@ -13931,6 +13931,7 @@ tests/webtbs/tw2602.pp svneol=native#text/plain
 tests/webtbs/tw2607.pp svneol=native#text/plain
 tests/webtbs/tw26162.pp svneol=native#text/pascal
 tests/webtbs/tw2620.pp svneol=native#text/plain
+tests/webtbs/tw26226.pp -text svneol=native#text/plain
 tests/webtbs/tw26230.pp svneol=native#text/plain
 tests/webtbs/tw2626.pp svneol=native#text/plain
 tests/webtbs/tw2627.pp svneol=native#text/plain

+ 2041 - 0
tests/webtbs/tw26226.pp

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