unit uIntX;
{$I ..\Include\IntXLib.inc}
interface
uses
Math,
SysUtils,
{$IFDEF DEBUG}
SyncObjs,
{$ENDIF DEBUG}
uIntXGlobalSettings,
uIntXSettings,
uEnums,
uStrings,
uIntXLibTypes;
type
///
/// numeric record which represents arbitrary-precision integers.
///
TIntX = record
///
/// big integer digits.
///
_digits: TIntXLibUInt32Array;
///
/// big integer digits length.
///
_length: UInt32;
///
/// big integer sign ("-" if true).
///
_negative: Boolean;
///
/// used to check if was Zero Initialized.
///
_zeroinithelper: Boolean;
class var
///
/// instance of .
///
_globalSettings: TIntXGlobalSettings;
///
/// instance of .
///
_settings: TIntXSettings;
///
/// used in .
///
_FS: TFormatSettings;
{$IFDEF DEBUG}
///
/// Critical Section for maximal error during FHT rounding (debug-mode only).
///
_maxFhtRoundErrorCriticalSection: TCriticalSection;
///
/// Maximal error during FHT rounding (debug-mode only).
///
MaxFhtRoundError: Double;
{$ENDIF DEBUG}
strict private
///
/// instance settings getter and setter.
///
function GetSettings: TIntXSettings;
procedure SetSettings(value: TIntXSettings);
///
/// isodd getter.
///
function GetIsOdd: Boolean;
///
/// isNegative getter.
///
function GetIsNegative: Boolean;
///
/// isZero getter.
///
function GetIsZero: Boolean;
///
/// isOne getter.
///
function GetIsOne: Boolean;
///
/// IsPowerOfTwo getter.
///
function GetIsPowerOfTwo: Boolean;
///
/// Getter function for
///
function GetClone: TIntX;
///
/// Getter function for
///
class function GetZero: TIntX; static;
///
/// Getter function for
///
class function GetOne: TIntX; static;
///
/// Getter function for
///
class function GetMinusOne: TIntX; static;
///
/// Getter function for
///
class function GetTen: TIntX; static;
///
/// Getter function for
///
class function GetGlobalSettings: TIntXGlobalSettings; static;
///
/// Initializes record instance from zero.
/// For internal use.
///
procedure InitFromZero();
///
/// Initializes record instance from value.
/// Doesn't initialize sign.
/// For internal use.
///
/// Unsigned Int64 value.
procedure InitFromUlong(value: UInt64);
///
/// Initializes record instance from another value.
/// For internal use.
///
/// TIntX value.
procedure InitFromIntX(value: TIntX);
///
/// Initializes record instance from digits array.
/// For internal use.
///
/// Big integer digits.
/// Big integer sign.
/// Big integer length.
procedure InitFromDigits(digits: TIntXLibUInt32Array; negative: Boolean;
mlength: UInt32);
public
///
/// instance settings property.
///
property Settings: TIntXSettings read GetSettings write SetSettings;
///
/// Gets flag indicating if big integer is odd.
///
property IsOdd: Boolean read GetIsOdd;
///
/// Gets flag indicating if big integer is negative.
///
property IsNegative: Boolean read GetIsNegative;
///
/// Gets flag indicating if big integer is zero.
///
property IsZero: Boolean read GetIsZero;
///
/// Gets flag indicating if big integer is one.
///
property IsOne: Boolean read GetIsOne;
///
/// Gets flag indicating if big integer is a power of two.
///
property IsPowerOfTwo: Boolean read GetIsPowerOfTwo;
///
/// Returns a copy of the current , with a unique copy of the data.
///
property Clone: TIntX read GetClone;
///
/// A Zero.
///
class property Zero: TIntX read GetZero;
///
/// A Positive One.
///
class property One: TIntX read GetOne;
///
/// A Negative One.
///
class property MinusOne: TIntX read GetMinusOne;
///
/// A Ten.
///
class property Ten: TIntX read GetTen;
///
/// global settings.
///
class property GlobalSettings: TIntXGlobalSettings read GetGlobalSettings;
// -- Class Constructor and Destructor --
class constructor Create();
class destructor Destroy();
// -- Constructors --
///
/// Creates new big integer from integer value.
///
/// Integer value to create big integer from.
constructor Create(value: Integer); overload;
///
/// Creates new big integer from unsigned integer value.
///
/// Unsigned integer value to create big integer from.
constructor Create(value: UInt32); overload;
///
/// Creates new big integer from Int64 value.
///
/// Int64 value to create big integer from.
constructor Create(value: Int64); overload;
///
/// Creates new big integer from unsigned Int64 value.
///
/// Unsigned Int64 value to create big integer from.
constructor Create(value: UInt64); overload;
///
/// Creates new big integer from a Double value.
/// replicates Microsoft Double to BigInteger Implementation.
///
///
/// Double value to create big integer from.
///
constructor Create(value: Double); overload;
///
/// Creates new big integer from array of it's "digits".
/// Digit with lower index has less weight.
///
/// Array of digits.
/// True if this number is negative.
/// is a null reference.
constructor Create(digits: TIntXLibUInt32Array; negative: Boolean);
overload;
///
/// Creates new from string.
///
/// Number as string.
constructor Create(const value: String); overload;
///
/// Creates new from string.
///
/// Number as string.
/// Number base.
constructor Create(const value: String; numberBase: UInt32); overload;
///
/// Copy constructor.
///
/// Value to copy from.
/// is a null reference.
constructor Create(value: TIntX); overload;
///
/// Creates new empty big integer with desired sign and length.
///
/// For internal use.
///
/// Desired digits length.
/// Desired integer sign.
constructor Create(mlength: UInt32; negative: Boolean); overload;
///
/// Creates new big integer from array of it's "digits" but with given length.
/// Digit with lower index has less weight.
///
/// For internal use.
///
/// Array of digits.
/// True if this number is negative.
/// Length to use for internal digits array.
/// is a null reference.
constructor Create(digits: TIntXLibUInt32Array; negative: Boolean;
mlength: UInt32); overload;
// -- Operators as functions and some other special mathematical functions --
///
/// Multiplies one object by another.
///
/// First big integer.
/// Second big integer.
/// Multiply mode set explicitly.
/// Multiply result.
class function Multiply(int1: TIntX; int2: TIntX; mode: TMultiplyMode)
: TIntX; static;
///
/// Divides one object by another.
///
/// First big integer.
/// Second big integer.
/// Divide mode.
/// Division result.
class function Divide(int1: TIntX; int2: TIntX; mode: TDivideMode)
: TIntX; static;
///
/// Divides one object by another and returns division modulo.
///
/// First big integer.
/// Second big integer.
/// Divide mode.
/// Modulo result.
class function Modulo(int1: TIntX; int2: TIntX; mode: TDivideMode)
: TIntX; static;
///
/// Divides one object by another.
/// Returns both divident and remainder
///
/// First big integer.
/// Second big integer.
/// Remainder big integer.
/// Division result.
class function DivideModulo(int1: TIntX; int2: TIntX; out modRes: TIntX)
: TIntX; overload; static;
///
/// Divides one object by another.
/// Returns both divident and remainder
///
/// First big integer.
/// Second big integer.
/// Remainder big integer.
/// Divide mode.
/// Division result.
class function DivideModulo(int1: TIntX; int2: TIntX; out modRes: TIntX;
mode: TDivideMode): TIntX; overload; static;
///
/// Returns a Non-Negative Random object using Pcg Random.
///
/// Random TIntX value.
class function Random(): TIntX; static;
///
/// Returns a Non-Negative Random object using Pcg Random within the specified Range. (Max not Included)
///
/// Minimum value.
/// Maximum value (Max not Included)
/// Random TIntX value.
class function RandomRange(Min: UInt32; Max: UInt32): TIntX; static;
///
/// Calculates absolute value of object.
///
/// value to get absolute value of.
/// Absolute value.
/// is a null reference.
class function AbsoluteValue(value: TIntX): TIntX; static;
///
/// The base-10 logarithm of the value.
///
/// The value.
/// The base-10 logarithm of the value.
/// Source : Microsoft .NET Reference on GitHub
/// is a null reference.
class function Log10(value: TIntX): Double; static;
///
/// Calculates the natural logarithm of the value.
///
///
/// The value.
///
///
/// The natural logarithm.
///
///
/// is a null reference.
///
///
/// Source : Microsoft .NET Reference on GitHub
///
class function Ln(value: TIntX): Double; static;
///
/// Calculates Logarithm of a number object for a specified base.
/// the largest power the base can be raised to that does not exceed the number.
///
/// base.
/// number to get log of.
/// Log value.
/// Source : Microsoft .NET Reference on GitHub
/// is a null reference.
class function LogN(base: Double; value: TIntX): Double; overload; static;
///
/// Calculates Integer Logarithm of a number object for a specified base.
/// the largest power the base can be raised to that does not exceed the number.
///
/// base.
/// number to get Integer log of.
/// Integer Log.
/// [IntegerLogN Implementation]
/// is a null reference.
/// is a null reference.
/// or is an invalid argument.
class function IntegerLogN(base: TIntX; number: TIntX): TIntX;
overload; static;
///
/// Calculates Square of object.
///
///
/// value to get square of.
///
///
/// Squared value.
///
///
/// is a null reference.
///
class function Square(value: TIntX): TIntX; static;
///
/// Calculates Integer SquareRoot of object
///
/// value to get Integer squareroot of.
/// Integer SquareRoot.
/// [IntegerSquareRoot Implementation]
/// is a null reference.
class function IntegerSquareRoot(value: TIntX): TIntX; static;
///
/// Calculates Factorial of object.
///
/// value to get factorial of.
/// Factorial.
/// is a null reference.
class function Factorial(value: TIntX): TIntX; static;
///
/// (Optimized GCD).
/// Returns a specified big integer holding the GCD (Greatest common Divisor) of
/// two big integers using Binary GCD (Stein's algorithm).
///
/// First big integer.
/// Second big integer.
/// GCD number.
/// [GCD Implementation]
/// [GCD Implementation Optimizations]
/// is a null reference.
/// is a null reference.
class function GCD(int1: TIntX; int2: TIntX): TIntX; static;
///
/// (LCM).
/// Returns a specified big integer holding the LCM (Least Common Multiple) of
/// two big integers.
///
/// First big integer.
/// Second big integer.
/// LCM number.
/// is a null reference.
/// is a null reference.
class function LCM(int1: TIntX; int2: TIntX): TIntX; static;
///
/// Calculate Modular Inverse for two objects using Euclids Extended Algorithm.
/// returns Zero if no Modular Inverse Exists for the Inputs
///
/// First big integer.
/// Second big integer.
/// Modular Inverse.
/// [Modular Inverse Explanation]
/// [Modular Inverse Implementation]
/// is a null reference.
/// is a null reference.
/// or is an invalid argument.
class function InvMod(int1: TIntX; int2: TIntX): TIntX; static;
///
/// Calculates Calculates Modular Exponentiation of object.
///
/// value to compute ModPow of.
/// exponent to use.
/// modulus to use.
/// Computed value.
/// [Modular Exponentiation Explanation]
/// is a null reference.
/// is a null reference.
/// is a null reference.
/// is an invalid argument.
/// is an invalid argument.
class function ModPow(value: TIntX; exponent: TIntX; modulus: TIntX)
: TIntX; static;
///
/// Calculates Bézoutsidentity for two objects using Euclids Extended Algorithm
///
/// first value.
/// second value.
/// first bezout value.
/// second bezout value.
/// GCD (Greatest Common Divisor) value.
/// [Bézout's identity Explanation]
/// [Bézout's identity Pseudocode using Extended Euclidean algorithm]
/// is a null reference.
/// is a null reference.
class function Bezoutsidentity(int1: TIntX; int2: TIntX; out bezOne: TIntX;
out bezTwo: TIntX): TIntX; static;
///
/// Checks if a object is Probably Prime using MillerRabin primality test.
///
/// big integer to check primality.
/// Accuracy parameter `k´ of the Miller-Rabin algorithm. Default is 5. The execution time is proportional to the value of the accuracy parameter.
/// Boolean value.
/// [MillerRabin primality test Explanation]
/// [MillerRabin primality test Implementation in C]
/// is a null reference.
class function IsProbablyPrime(value: TIntX; Accuracy: Integer = 5)
: Boolean; static;
///
/// The Max Between Two values.
///
///
/// left value.
///
///
/// right value.
///
///
/// The Maximum value.
///
///
/// is a null reference.
///
///
/// is a null reference.
///
class function Max(left: TIntX; right: TIntX): TIntX; static;
///
/// The Min Between Two values.
///
/// left value.
/// right value.
/// The Minimum value.
/// is a null reference.
/// is a null reference.
class function Min(left: TIntX; right: TIntX): TIntX; static;
///
/// Returns a specified big integer raised to the specified power.
///
/// Number to raise.
/// Power.
/// Number in given power.
class function Pow(value: TIntX; power: UInt32): TIntX; overload; static;
///
/// Returns a specified big integer raised to the specified power.
///
/// Number to raise.
/// Power.
/// Multiply mode set explicitly.
/// Number in given power.
class function Pow(value: TIntX; power: UInt32; multiplyMode: TMultiplyMode)
: TIntX; overload; static;
// String output functions
///
/// Returns decimal string representation of this object.
///
/// Decimal number in string.
function ToString(): String; overload;
///
/// Returns string representation of this object in given base.
///
/// Base of system in which to do output.
/// Object string representation.
function ToString(numberBase: UInt32): String; overload;
///
/// Returns string representation of this object in given base.
///
/// Base of system in which to do output.
/// Use uppercase for bases from 11 to 16 (which use letters A-F).
/// Object string representation.
function ToString(numberBase: UInt32; UpperCase: Boolean): String; overload;
///
/// Returns string representation of this object in given base using custom alphabet.
///
/// Base of system in which to do output.
/// Alphabet which contains chars used to represent big integer, char position is coresponding digit value.
/// Object string representation.
function ToString(numberBase: UInt32; const alphabet: String)
: String; overload;
// -- Conversion functions --
///
/// Converts the specified to a Double, if this is possible. returns Infinity (+ or -) if the
/// value of the is too large or too small.
/// uses method found in Microsoft BigInteger source on github.
///
function AsDouble: Double;
///
/// Converts the specified to an Integer, if this is possible. Raises an EOverFlowException if the
/// value of the is too large.
///
function AsInteger: Integer;
///
/// Converts the specified to a UInt32, if this is possible. Raises an EOverFlowException if the
/// value of the is too large or is negative.
///
function AsUInt32: UInt32;
///
/// Converts the specified to an Int64, if this is possible. Raises an EOverFlowException if the
/// value of the is too large.
///
function AsInt64: Int64;
///
/// Converts the specified to a UInt64, if this is possible. Raises an EOverFlowException if the
/// value of the is too large or is negative.
///
function AsUInt64: UInt64;
// String parsing functions
///
/// Parses provided string representation of object in decimal base.
/// If number starts from "0" then it's treated as octal; if number starts from "$" or "0x"
/// then it's treated as hexadecimal.
///
/// Number as string.
/// Parsed TIntX object.
class function Parse(const value: String): TIntX; overload; static;
///
/// Parses provided string representation of object.
///
/// Number as string.
/// Number base.
/// Parsed TIntX object.
class function Parse(const value: String; numberBase: UInt32): TIntX;
overload; static;
///
/// Parses provided string representation of object using custom alphabet.
///
/// Number as string.
/// Number base.
/// Alphabet which contains chars used to represent big integer, char position is coresponding digit value.
/// Parsed TIntX object.
class function Parse(const value: String; numberBase: UInt32;
const alphabet: String): TIntX; overload; static;
///
/// Parses provided string representation of object in decimal base.
/// If number starts from "0" then it's treated as octal; if number starts from "$" or "0x"
/// then it's treated as hexadecimal.
///
/// Number as string.
/// Parse mode.
/// Parsed TIntX object.
class function Parse(const value: String; mode: TParseMode): TIntX;
overload; static;
///
/// Parses provided string representation of object.
///
/// Number as string.
/// Number base.
/// Parse mode.
/// Parsed TIntX object.
class function Parse(const value: String; numberBase: UInt32;
mode: TParseMode): TIntX; overload; static;
///
/// Parses provided string representation of object using custom alphabet.
///
/// Number as string.
/// Number base.
/// Alphabet which contains chars used to represent big integer, char position is coresponding digit value.
/// Parse mode.
/// Parsed TIntX object.
class function Parse(const value: String; numberBase: UInt32;
const alphabet: String; mode: TParseMode): TIntX; overload; static;
///
/// Returns equality of this with another big integer.
///
/// Big integer to compare with.
/// True if equals.
function Equals(n: TIntX): Boolean; overload;
///
/// Returns equality of this with another integer.
///
/// Integer to compare with.
/// True if equals.
function Equals(n: Integer): Boolean; overload;
///
/// Returns equality of this with another unsigned integer.
///
/// Unsigned integer to compare with.
/// True if equals.
function Equals(n: UInt32): Boolean; overload;
///
/// Returns equality of this with another Int64.
///
/// Int64 to compare with.
/// True if equals.
function Equals(n: Int64): Boolean; overload;
///
/// Returns equality of this with another unsigned Int64.
///
/// unsigned Int64 to compare with.
/// True if equals.
function Equals(n: UInt64): Boolean; overload;
///
/// Compares current object with another big integer.
///
/// Big integer to compare with.
/// 1 if object is bigger than , -1 if object is smaller than , 0 if they are equal.
function CompareTo(n: TIntX): Integer; overload;
///
/// Compares current object with another integer.
///
/// Integer to compare with.
/// 1 if object is bigger than , -1 if object is smaller than , 0 if they are equal.
function CompareTo(n: Integer): Integer; overload;
///
/// Compares current object with another unsigned integer.
///
/// Unsigned integer to compare with.
/// 1 if object is bigger than , -1 if object is smaller than , 0 if they are equal.
function CompareTo(n: UInt32): Integer; overload;
///
/// Compares current object with another Int64.
///
/// Int64 to compare with.
/// 1 if object is bigger than , -1 if object is smaller than , 0 if they are equal.
function CompareTo(n: Int64): Integer; overload;
///
/// Compares current object with another UInt64.
///
/// UInt64 to compare with.
/// 1 if object is bigger than , -1 if object is smaller than , 0 if they are equal.
function CompareTo(n: UInt64): Integer; overload;
///
/// Frees extra space not used by digits.
///
procedure Normalize();
///
/// Retrieves this internal state as digits array and sign.
/// Can be used for serialization and other purposes.
/// Note: please use constructor instead to clone object.
///
/// Digits array.
/// Is negative integer.
/// Is zero initialized?.
procedure GetInternalState(out digits: TIntXLibUInt32Array;
out negative: Boolean; out zeroinithelper: Boolean);
///
/// Frees extra space not used by digits only if auto-normalize is set for the instance.
///
procedure TryNormalize();
///
/// Compare two records to check if they are same.
///
/// Record one to compare.
/// Record two to compare.
/// Boolean value (True if they contain the Same contents else False).
class function CompareRecords(Rec1: TIntX; Rec2: TIntX): Boolean;
static; inline;
// -- Comparison operators --
///
/// Compares two objects and returns true if their internal state is equal.
///
/// First big integer.
/// Second big integer.
/// True if equals.
class operator Equal(int1: TIntX; int2: TIntX): Boolean;
///
/// Compares object with integer and returns true if their internal state is equal.
///
/// big integer.
/// integer.
/// True if equals.
class operator Equal(int1: TIntX; int2: Integer): Boolean;
///
/// Compares integer with object and returns true if their internal state is equal.
///
/// integer.
/// big integer.
/// True if equals.
class operator Equal(int1: Integer; int2: TIntX): Boolean;
///
/// Compares object with unsigned integer and returns true if their internal state is equal.
///
/// big integer.
/// unsigned integer.
/// True if equals.
class operator Equal(int1: TIntX; int2: UInt32): Boolean;
///
/// Compares unsigned integer with object and returns true if their internal state is equal.
///
/// unsigned integer.
/// big integer.
/// True if equals.
class operator Equal(int1: UInt32; int2: TIntX): Boolean;
///
/// Compares object with Int64 and returns true if their internal state is equal.
///
/// big integer.
/// Int64.
/// True if equals.
class operator Equal(int1: TIntX; int2: Int64): Boolean;
///
/// Compares Int64 with object and returns true if their internal state is equal.
///
/// Int64.
/// big integer.
/// True if equals.
class operator Equal(int1: Int64; int2: TIntX): Boolean;
///
/// Compares object with UInt64 and returns true if their internal state is equal.
///
/// big integer.
/// UInt64.
/// True if equals.
class operator Equal(int1: TIntX; int2: UInt64): Boolean;
///
/// Compares UInt64 with object and returns true if their internal state is equal.
///
/// UInt64.
/// big integer.
/// True if equals.
class operator Equal(int1: UInt64; int2: TIntX): Boolean;
///
/// Compares two objects and returns true if their internal state is not equal.
///
/// First big integer.
/// Second big integer.
/// True if not equals.
class operator NotEqual(int1: TIntX; int2: TIntX): Boolean;
///
/// Compares object with integer and returns true if their internal state is not equal.
///
/// big integer.
/// integer.
/// True if not equals.
class operator NotEqual(int1: TIntX; int2: Integer): Boolean;
///
/// Compares integer with object and returns true if their internal state is not equal.
///
/// integer.
/// big integer.
/// True if not equals.
class operator NotEqual(int1: Integer; int2: TIntX): Boolean;
///
/// Compares object with unsigned integer and returns true if their internal state is not equal.
///
/// big integer.
/// unsigned integer.
/// True if not equals.
class operator NotEqual(int1: TIntX; int2: UInt32): Boolean;
///
/// Compares unsigned integer with object and returns true if their internal state is not equal.
///
/// unsigned integer.
/// big integer.
/// True if not equals.
class operator NotEqual(int1: UInt32; int2: TIntX): Boolean;
///
/// Compares object with Int64 and returns true if their internal state is not equal.
///
/// big integer.
/// Int64.
/// True if not equals.
class operator NotEqual(int1: TIntX; int2: Int64): Boolean;
///
/// Compares Int64 with object and returns true if their internal state is not equal.
///
/// Int64.
/// big integer.
/// True if not equals.
class operator NotEqual(int1: Int64; int2: TIntX): Boolean;
///
/// Compares object with UInt64 and returns true if their internal state is not equal.
///
/// big integer.
/// UInt64.
/// True if not equals.
class operator NotEqual(int1: TIntX; int2: UInt64): Boolean;
///
/// Compares UInt64 with object and returns true if their internal state is not equal.
///
/// UInt64.
/// big integer.
/// True if not equals.
class operator NotEqual(int1: UInt64; int2: TIntX): Boolean;
///
/// Compares two objects and returns true if first is greater.
///
/// First big integer.
/// Second big integer.
/// True if first is greater.
class operator GreaterThan(int1: TIntX; int2: TIntX): Boolean;
///
/// Compares object with integer and returns true if first is greater.
///
/// big integer.
/// integer.
/// True if first is greater.
class operator GreaterThan(int1: TIntX; int2: Integer): Boolean;
///
/// Compares integer with object and returns true if first is greater.
///
/// integer.
/// big integer.
/// True if first is greater.
class operator GreaterThan(int1: Integer; int2: TIntX): Boolean;
///
/// Compares object with unsigned integer and returns true if first is greater.
///
/// big integer.
/// unsigned integer.
/// True if first is greater.
class operator GreaterThan(int1: TIntX; int2: UInt32): Boolean;
///
/// Compares unsigned integer with object and returns true if first is greater.
///
/// unsigned integer.
/// big integer.
/// True if first is greater.
class operator GreaterThan(int1: UInt32; int2: TIntX): Boolean;
///
/// Compares object with Int64 and returns true if first is greater.
///
/// big integer.
/// Int64.
/// True if first is greater.
class operator GreaterThan(int1: TIntX; int2: Int64): Boolean;
///
/// Compares Int64 with object and returns true if first is greater.
///
/// Int64.
/// big integer.
/// True if first is greater.
class operator GreaterThan(int1: Int64; int2: TIntX): Boolean;
///
/// Compares object with UInt64 and returns true if first is greater.
///
/// big integer.
/// UInt64.
/// True if first is greater.
class operator GreaterThan(int1: TIntX; int2: UInt64): Boolean;
///
/// Compares UInt64 with object and returns true if first is greater.
///
/// UInt64.
/// big integer.
/// True if first is greater.
class operator GreaterThan(int1: UInt64; int2: TIntX): Boolean;
///
/// Compares two objects and returns true if first is greater or equal.
///
/// First big integer.
/// Second big integer.
/// True if first is greater or equal.
class operator GreaterThanOrEqual(int1: TIntX; int2: TIntX): Boolean;
///
/// Compares object with integer and returns true if first is greater or equal.
///
/// big integer.
/// integer.
/// True if first is greater or equal.
class operator GreaterThanOrEqual(int1: TIntX; int2: Integer): Boolean;
///
/// Compares integer with object and returns true if first is greater or equal.
///
/// integer.
/// big integer.
/// True if first is greater or equal.
class operator GreaterThanOrEqual(int1: Integer; int2: TIntX): Boolean;
///
/// Compares object with unsigned integer and returns true if first is greater or equal.
///
/// big integer.
/// unsigned integer.
/// True if first is greater or equal.
class operator GreaterThanOrEqual(int1: TIntX; int2: UInt32): Boolean;
///
/// Compares unsigned integer with object and returns true if first is greater or equal.
///
/// unsigned integer.
/// big integer.
/// True if first is greater or equal.
class operator GreaterThanOrEqual(int1: UInt32; int2: TIntX): Boolean;
///
/// Compares object with Int64 and returns true if first is greater or equal.
///
/// big integer.
/// Int64.
/// True if first is greater or equal.
class operator GreaterThanOrEqual(int1: TIntX; int2: Int64): Boolean;
///
/// Compares Int64 with object and returns true if first is greater or equal.
///
/// Int64.
/// big integer.
/// True if first is greater or equal.
class operator GreaterThanOrEqual(int1: Int64; int2: TIntX): Boolean;
///
/// Compares object with UInt64 and returns true if first is greater or equal.
///
/// big integer.
/// UInt64.
/// True if first is greater or equal.
class operator GreaterThanOrEqual(int1: TIntX; int2: UInt64): Boolean;
///
/// Compares UInt64 with object and returns true if first is greater or equal.
///
/// UInt64.
/// big integer.
/// True if first is greater or equal.
class operator GreaterThanOrEqual(int1: UInt64; int2: TIntX): Boolean;
///
/// Compares two objects and returns true if first is lighter.
///
/// First big integer.
/// Second big integer.
/// True if first is lighter.
class operator LessThan(int1: TIntX; int2: TIntX): Boolean;
///
/// Compares object with integer and returns true if first is lighter.
///
/// big integer.
/// integer.
/// True if first is lighter.
class operator LessThan(int1: TIntX; int2: Integer): Boolean;
///
/// Compares integer with object and returns true if first is lighter.
///
/// integer.
/// big integer.
/// True if first is lighter.
class operator LessThan(int1: Integer; int2: TIntX): Boolean;
///
/// Compares object with unsigned integer and returns true if first is lighter.
///
/// big integer.
/// unsigned integer.
/// True if first is lighter.
class operator LessThan(int1: TIntX; int2: UInt32): Boolean;
///
/// Compares unsigned integer with object and returns true if first is lighter.
///
/// unsigned integer.
/// big integer.
/// True if first is lighter.
class operator LessThan(int1: UInt32; int2: TIntX): Boolean;
///
/// Compares object with Int64 and returns true if first is lighter.
///
/// big integer.
/// Int64.
/// True if first is lighter.
class operator LessThan(int1: TIntX; int2: Int64): Boolean;
///
/// Compares Int64 with object and returns true if first is lighter.
///
/// Int64.
/// big integer.
/// True if first is lighter.
class operator LessThan(int1: Int64; int2: TIntX): Boolean;
///
/// Compares object with UInt64 and returns true if first is lighter.
///
/// big integer.
/// UInt64.
/// True if first is lighter.
class operator LessThan(int1: TIntX; int2: UInt64): Boolean;
///
/// Compares UInt64 with object and returns true if first is lighter.
///
/// UInt64.
/// big integer.
/// True if first is lighter.
class operator LessThan(int1: UInt64; int2: TIntX): Boolean;
///
/// Compares two objects and returns true if first is lighter or equal.
///
/// First big integer.
/// Second big integer.
/// True if first is lighter or equal.
class operator LessThanOrEqual(int1: TIntX; int2: TIntX): Boolean;
///
/// Compares object with integer and returns true if first is lighter or equal.
///
/// big integer.
/// integer.
/// True if first is lighter or equal.
class operator LessThanOrEqual(int1: TIntX; int2: Integer): Boolean;
///
/// Compares integer with object and returns true if first is lighter or equal.
///
/// integer.
/// big integer.
/// True if first is lighter or equal.
class operator LessThanOrEqual(int1: Integer; int2: TIntX): Boolean;
///
/// Compares object with unsigned integer and returns true if first is lighter or equal.
///
/// big integer.
/// unsigned integer.
/// True if first is lighter or equal.
class operator LessThanOrEqual(int1: TIntX; int2: UInt32): Boolean;
///
/// Compares unsigned integer with object and returns true if first is lighter or equal.
///
/// unsigned integer.
/// big integer.
/// True if first is lighter or equal.
class operator LessThanOrEqual(int1: UInt32; int2: TIntX): Boolean;
///
/// Compares object with Int64 and returns true if first is lighter or equal.
///
/// big integer.
/// Int64.
/// True if first is lighter or equal.
class operator LessThanOrEqual(int1: TIntX; int2: Int64): Boolean;
///
/// Compares Int64 with object and returns true if first is lighter or equal.
///
/// Int64.
/// big integer.
/// True if first is lighter or equal.
class operator LessThanOrEqual(int1: Int64; int2: TIntX): Boolean;
///
/// Compares object with UInt64 and returns true if first is lighter or equal.
///
/// big integer.
/// UInt64.
/// True if first is lighter or equal.
class operator LessThanOrEqual(int1: TIntX; int2: UInt64): Boolean;
///
/// Compares UInt64 with object and returns true if first is lighter or equal.
///
/// UInt64.
/// big integer.
/// True if first is lighter or equal.
class operator LessThanOrEqual(int1: UInt64; int2: TIntX): Boolean;
// -- Arithmetic operators --
///
/// Adds one object to another.
///
/// First big integer.
/// Second big integer.
/// Addition result.
class operator Add(int1: TIntX; int2: TIntX): TIntX;
///
/// Subtracts one object from another.
///
/// First big integer.
/// Second big integer.
/// Subtraction result.
class operator Subtract(int1: TIntX; int2: TIntX): TIntX;
///
/// Multiplies one object by another.
///
/// First big integer.
/// Second big integer.
/// Multiply result.
class operator Multiply(int1: TIntX; int2: TIntX): TIntX;
///
/// Divides one object by another.
///
/// First big integer.
/// Second big integer.
/// Division result.
class operator IntDivide(int1: TIntX; int2: TIntX): TIntX;
///
/// Divides one object by another and returns division modulo.
///
/// First big integer.
/// Second big integer.
/// Modulo result.
class operator modulus(int1: TIntX; int2: TIntX): TIntX;
///
/// Shifts object by selected bits count to the left.
///
/// Big integer.
/// Bits count.
/// Shifting result.
class operator LeftShift(IntX: TIntX; shift: Integer): TIntX;
///
/// Shifts object by selected bits count to the right.
///
/// Big integer.
/// Bits count.
/// Shifting result.
class operator RightShift(IntX: TIntX; shift: Integer): TIntX;
///
/// Returns the same value.
///
/// Initial value.
/// The same value, but new object.
/// is a null reference.
class operator Positive(value: TIntX): TIntX;
///
/// Returns the same value, but with other sign.
///
/// Initial value.
/// The same value, but with other sign.
/// is a null reference.
class operator negative(value: TIntX): TIntX;
///
/// Returns increased value.
///
/// Initial value.
/// Increased value.
/// is a null reference.
class operator Inc(value: TIntX): TIntX;
///
/// Returns decreased value.
///
/// Initial value.
/// Decreased value.
/// is a null reference.
class operator Dec(value: TIntX): TIntX;
// -- Logical and bitwise operators --
///
/// Performs bitwise OR for two big integers.
///
/// First big integer.
/// Second big integer.
/// Resulting big integer.
class operator BitwiseOr(int1: TIntX; int2: TIntX): TIntX;
///
/// Performs bitwise AND for two big integers.
///
/// First big integer.
/// Second big integer.
/// Resulting big integer.
class operator BitwiseAnd(int1: TIntX; int2: TIntX): TIntX;
///
/// Performs bitwise XOR for two big integers.
///
/// First big integer.
/// Second big integer.
/// Resulting big integer.
class operator BitwiseXor(int1: TIntX; int2: TIntX): TIntX;
///
/// Performs bitwise NOT for big integer.
///
/// Big integer.
/// Resulting big integer.
///
/// ** In Delphi, You cannot overload the bitwise not operator, as BitwiseNot is not
/// supported by the compiler. You have to overload the logical 'not' operator
/// instead.
/// **A bitwise not might be An Integer XOR -1 (Not Sure Though)**
///
/// [For more Information]
class operator LogicalNot(value: TIntX): TIntX;
// -- Implicit conversion operators --
///
/// Implicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Implicit(value: Byte): TIntX;
///
/// Implicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Implicit(value: ShortInt): TIntX;
///
/// Implicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Implicit(value: SmallInt): TIntX;
///
/// Implicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Implicit(value: Word): TIntX;
///
/// Implicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Implicit(value: Integer): TIntX;
///
/// Implicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Implicit(value: UInt32): TIntX;
///
/// Implicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Implicit(value: Int64): TIntX;
///
/// Implicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Implicit(value: UInt64): TIntX;
// -- Explicit conversion operators --
///
/// Explicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Explicit(value: Double): TIntX;
///
/// Explicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Explicit(value: TIntX): Byte;
///
/// Explicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Explicit(value: TIntX): ShortInt;
///
/// Explicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Explicit(value: TIntX): SmallInt;
///
/// Explicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Explicit(value: TIntX): Word;
///
/// Explicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Explicit(value: TIntX): Integer;
///
/// Explicitly converts to .
///
/// Value to convert.
/// Conversion result.
/// is a null reference.
class operator Explicit(value: TIntX): UInt32;
///
/// Explicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Explicit(value: TIntX): Int64;
///
/// Explicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Explicit(value: TIntX): UInt64;
///
/// Explicitly converts to .
///
/// Value to convert.
/// Conversion result.
class operator Explicit(value: TIntX): Double;
end;
var
///
/// Temporary Variable to Hold Zero.
///
ZeroX: TIntX;
///
/// Temporary Variable to Hold One.
///
OneX: TIntX;
///
/// Temporary Variable to Hold Minus One.
///
MinusOneX: TIntX;
///
/// Temporary Variable to Hold Ten .
///
TenX: TIntX;
implementation
uses
uConstants,
uMultiplyManager,
uDivideManager,
uStringConvertManager,
uParseManager,
uDigitHelper,
uOpHelper,
uStrRepHelper;
// static constructor
class constructor TIntX.Create();
begin
_globalSettings := TIntXGlobalSettings.Create;
_settings := TIntXSettings.Create(TIntX.GlobalSettings);
// Global FormatSettings
{$IFDEF FPC}
_FS := DefaultFormatSettings;
{$ELSE}
{$IFDEF DELPHIXE_UP}
_FS := TFormatSettings.Create;
{$ELSE}
GetLocaleFormatSettings(0, _FS);
{$ENDIF DELPHIXE_UP}
{$ENDIF FPC}
// Create a Zero TIntX (a big integer with value as Zero)
ZeroX := TIntX.Create(0);
// Create a One TIntX (a big integer with value as One)
OneX := TIntX.Create(1);
// Create a MinusOne TIntX (a big integer with value as Negative One)
MinusOneX := TIntX.Create(-1);
// Create a Ten TIntX (a big integer with value as Ten)
TenX := TIntX.Create(10);
{$IFDEF DEBUG}
_maxFhtRoundErrorCriticalSection := TCriticalSection.Create;
{$ENDIF DEBUG}
end;
class destructor TIntX.Destroy();
begin
{$IFDEF DEBUG}
_maxFhtRoundErrorCriticalSection.Free;
{$ENDIF DEBUG}
_globalSettings.Free;
_settings.Free;
end;
class function TIntX.CompareRecords(Rec1: TIntX; Rec2: TIntX): Boolean;
begin
if Length(Rec1._digits) <> Length(Rec2._digits) then
begin
result := false;
Exit;
end;
result := (CompareMem(Pointer(Rec1._digits), Pointer(Rec2._digits),
Length(Rec1._digits) * SizeOf(UInt32)) and (Rec1._length = Rec2._length) and
(Rec1._negative = Rec2._negative) and
(Rec1._zeroinithelper = Rec2._zeroinithelper));
end;
class function TIntX.GetZero: TIntX;
begin
result := ZeroX;
end;
class function TIntX.GetOne: TIntX;
begin
result := OneX;
end;
class function TIntX.GetMinusOne: TIntX;
begin
result := MinusOneX;
end;
class function TIntX.GetTen: TIntX;
begin
result := TenX;
end;
class function TIntX.GetGlobalSettings: TIntXGlobalSettings;
begin
result := _globalSettings;
end;
constructor TIntX.Create(value: Integer);
begin
if (value = 0) then
begin
// Very specific fast processing for zero values
InitFromZero();
end
else
begin
// Prepare internal fields
_length := 1;
SetLength(_digits, _length);
// Fill the only big integer digit
TDigitHelper.ToUInt32WithSign(value, _digits[0], _negative,
_zeroinithelper);
end;
end;
constructor TIntX.Create(value: UInt32);
begin
if (value = 0) then
begin
// Very specific fast processing for zero values
InitFromZero();
end
else
begin
// Prepare internal fields
SetLength(_digits, 1);
_digits[0] := value;
_length := 1;
// Initialized _negative to False by default since this type does not have
// negative values.
_negative := false;
end;
end;
constructor TIntX.Create(value: Int64);
var
newValue: UInt64;
begin
if (value = 0) then
begin
// Very specific fast processing for zero values
InitFromZero();
end
else
begin
// Fill the only big integer digit
TDigitHelper.ToUInt64WithSign(value, newValue, _negative, _zeroinithelper);
InitFromUlong(newValue);
end;
end;
constructor TIntX.Create(value: UInt64);
begin
if (value = 0) then
begin
// Very specific fast processing for zero values
InitFromZero();
end
else
begin
InitFromUlong(value);
// Initialized _negative to False by default since this type does not have
// negative values.
_negative := false;
end;
end;
constructor TIntX.Create(value: Double);
begin
// Exceptions
if (IsInfinite(value)) then
raise EOverflowException.Create(uStrings.Overflow_TIntXInfinity);
if (IsNaN(value)) then
raise EOverflowException.Create(uStrings.Overflow_NotANumber);
_digits := Nil;
TOpHelper.SetDigitsFromDouble(value, _digits, Self);
end;
constructor TIntX.Create(digits: TIntXLibUInt32Array; negative: Boolean);
begin
// Exception
if (digits = Nil) then
begin
raise EArgumentNilException.Create('digits');
end;
InitFromDigits(digits, negative, TDigitHelper.GetRealDigitsLength(digits,
UInt32(Length(digits))));
end;
constructor TIntX.Create(const value: String);
var
IntX: TIntX;
begin
IntX := Parse(value);
InitFromIntX(IntX);
end;
constructor TIntX.Create(const value: String; numberBase: UInt32);
var
IntX: TIntX;
begin
IntX := Parse(value, numberBase);
InitFromIntX(IntX);
end;
constructor TIntX.Create(value: TIntX);
begin
// Exception
if (value = Default (TIntX)) then
begin
raise EArgumentNilException.Create('value');
end;
InitFromIntX(value);
end;
constructor TIntX.Create(mlength: UInt32; negative: Boolean);
begin
_length := mlength;
SetLength(_digits, _length);
_negative := negative;
end;
constructor TIntX.Create(digits: TIntXLibUInt32Array; negative: Boolean;
mlength: UInt32);
begin
// Exception
if (digits = Nil) then
begin
raise EArgumentNilException.Create('digits');
end;
InitFromDigits(digits, negative, mlength);
end;
function TIntX.GetSettings: TIntXSettings;
begin
result := _settings;
end;
procedure TIntX.SetSettings(value: TIntXSettings);
begin
_settings := value;
end;
function TIntX.GetIsOdd: Boolean;
begin
result := (_length > 0) and ((_digits[0] and 1) = 1);
end;
function TIntX.GetIsNegative: Boolean;
begin
result := _negative;
end;
function TIntX.GetIsZero: Boolean;
begin
result := Self.Equals(TIntX.Zero);
end;
function TIntX.GetIsOne: Boolean;
begin
result := Self.Equals(TIntX.One);
end;
function TIntX.GetIsPowerOfTwo: Boolean;
var
iu: Integer;
begin
if IsNegative then
begin
result := false;
Exit;
end;
if Self <= TConstants.MaxUInt64Value then
begin
result := (not Self.IsZero) and (Self and (Self - 1) = 0);
Exit;
end;
iu := Length(_digits) - 1;
if ((_digits[iu] and (_digits[iu] - 1)) <> 0) then
begin
result := false;
Exit;
end;
Dec(iu);
while iu >= 0 do
begin
if (_digits[iu] <> 0) then
begin
result := false;
Exit;
end;
Dec(iu);
end;
result := true;
Exit;
end;
function TIntX.GetClone: TIntX;
begin
result._digits := Copy(Self._digits);
result._length := Self._length;
result._negative := Self._negative;
result._zeroinithelper := Self._zeroinithelper;
end;
class operator TIntX.Equal(int1: TIntX; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int1, int2, false) = 0;
end;
class operator TIntX.Equal(int1: TIntX; int2: Integer): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) = 0;
end;
class operator TIntX.Equal(int1: Integer; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) = 0;
end;
class operator TIntX.Equal(int1: TIntX; int2: UInt32): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) = 0;
end;
class operator TIntX.Equal(int1: UInt32; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) = 0;
end;
class operator TIntX.Equal(int1: TIntX; int2: Int64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) = 0;
end;
class operator TIntX.Equal(int1: Int64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) = 0;
end;
class operator TIntX.Equal(int1: TIntX; int2: UInt64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) = 0;
end;
class operator TIntX.Equal(int1: UInt64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) = 0;
end;
class operator TIntX.NotEqual(int1: TIntX; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int1, int2, false) <> 0;
end;
class operator TIntX.NotEqual(int1: TIntX; int2: Integer): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) <> 0;
end;
class operator TIntX.NotEqual(int1: Integer; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) <> 0;
end;
class operator TIntX.NotEqual(int1: TIntX; int2: UInt32): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) <> 0;
end;
class operator TIntX.NotEqual(int1: UInt32; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) <> 0;
end;
class operator TIntX.NotEqual(int1: TIntX; int2: Int64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) <> 0;
end;
class operator TIntX.NotEqual(int1: Int64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) <> 0;
end;
class operator TIntX.NotEqual(int1: TIntX; int2: UInt64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) <> 0;
end;
class operator TIntX.NotEqual(int1: UInt64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) <> 0;
end;
class operator TIntX.GreaterThan(int1: TIntX; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int1, int2, true) > 0;
end;
class operator TIntX.GreaterThan(int1: TIntX; int2: Integer): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) > 0;
end;
class operator TIntX.GreaterThan(int1: Integer; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) < 0;
end;
class operator TIntX.GreaterThan(int1: TIntX; int2: UInt32): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) > 0;
end;
class operator TIntX.GreaterThan(int1: UInt32; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) < 0;
end;
class operator TIntX.GreaterThan(int1: TIntX; int2: Int64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) > 0;
end;
class operator TIntX.GreaterThan(int1: Int64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) < 0;
end;
class operator TIntX.GreaterThan(int1: TIntX; int2: UInt64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) > 0;
end;
class operator TIntX.GreaterThan(int1: UInt64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) < 0;
end;
class operator TIntX.GreaterThanOrEqual(int1: TIntX; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int1, int2, true) >= 0;
end;
class operator TIntX.GreaterThanOrEqual(int1: TIntX; int2: Integer): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) >= 0;
end;
class operator TIntX.GreaterThanOrEqual(int1: Integer; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) <= 0;
end;
class operator TIntX.GreaterThanOrEqual(int1: TIntX; int2: UInt32): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) >= 0;
end;
class operator TIntX.GreaterThanOrEqual(int1: UInt32; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) <= 0;
end;
class operator TIntX.GreaterThanOrEqual(int1: TIntX; int2: Int64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) >= 0;
end;
class operator TIntX.GreaterThanOrEqual(int1: Int64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) <= 0;
end;
class operator TIntX.GreaterThanOrEqual(int1: TIntX; int2: UInt64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) >= 0;
end;
class operator TIntX.GreaterThanOrEqual(int1: UInt64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) <= 0;
end;
class operator TIntX.LessThan(int1: TIntX; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int1, int2, true) < 0;
end;
class operator TIntX.LessThan(int1: TIntX; int2: Integer): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) < 0;
end;
class operator TIntX.LessThan(int1: Integer; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) > 0;
end;
class operator TIntX.LessThan(int1: TIntX; int2: UInt32): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) < 0;
end;
class operator TIntX.LessThan(int1: UInt32; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) > 0;
end;
class operator TIntX.LessThan(int1: TIntX; int2: Int64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) < 0;
end;
class operator TIntX.LessThan(int1: Int64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) > 0;
end;
class operator TIntX.LessThan(int1: TIntX; int2: UInt64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) < 0;
end;
class operator TIntX.LessThan(int1: UInt64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) > 0;
end;
class operator TIntX.LessThanOrEqual(int1: TIntX; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int1, int2, true) <= 0;
end;
class operator TIntX.LessThanOrEqual(int1: TIntX; int2: Integer): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) <= 0;
end;
class operator TIntX.LessThanOrEqual(int1: Integer; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) >= 0;
end;
class operator TIntX.LessThanOrEqual(int1: TIntX; int2: UInt32): Boolean;
begin
result := TOpHelper.Cmp(int1, int2) <= 0;
end;
class operator TIntX.LessThanOrEqual(int1: UInt32; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, int1) >= 0;
end;
class operator TIntX.LessThanOrEqual(int1: TIntX; int2: Int64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) <= 0;
end;
class operator TIntX.LessThanOrEqual(int1: Int64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) >= 0;
end;
class operator TIntX.LessThanOrEqual(int1: TIntX; int2: UInt64): Boolean;
begin
result := TOpHelper.Cmp(int1, TIntX.Create(int2), false) <= 0;
end;
class operator TIntX.LessThanOrEqual(int1: UInt64; int2: TIntX): Boolean;
begin
result := TOpHelper.Cmp(int2, TIntX.Create(int1), false) >= 0;
end;
class operator TIntX.Add(int1: TIntX; int2: TIntX): TIntX;
begin
result := TOpHelper.AddSub(int1, int2, false);
end;
class operator TIntX.Subtract(int1: TIntX; int2: TIntX): TIntX;
begin
result := TOpHelper.AddSub(int1, int2, true);
end;
class operator TIntX.Multiply(int1: TIntX; int2: TIntX): TIntX;
begin
result := TMultiplyManager.GetCurrentMultiplier().Multiply(int1, int2);
end;
class operator TIntX.IntDivide(int1: TIntX; int2: TIntX): TIntX;
var
modRes: TIntX;
begin
result := TDivideManager.GetCurrentDivider().DivMod(int1, int2, modRes,
TDivModResultFlags.dmrfDiv);
end;
class operator TIntX.modulus(int1: TIntX; int2: TIntX): TIntX;
var
modRes: TIntX;
begin
TDivideManager.GetCurrentDivider().DivMod(int1, int2, modRes,
TDivModResultFlags.dmrfMod);
result := modRes;
end;
class operator TIntX.LeftShift(IntX: TIntX; shift: Integer): TIntX;
begin
result := TOpHelper.Sh(IntX, shift, true);
end;
class operator TIntX.RightShift(IntX: TIntX; shift: Integer): TIntX;
begin
result := TOpHelper.Sh(IntX, shift, false);
end;
class operator TIntX.Positive(value: TIntX): TIntX;
begin
// Exception
if TIntX.CompareRecords(value, Default (TIntX)) then
begin
raise EArgumentNilException.Create('value');
end;
result := TIntX.Create(value);
end;
class operator TIntX.negative(value: TIntX): TIntX;
var
newValue: TIntX;
begin
// Exception
if TIntX.CompareRecords(value, Default (TIntX)) then
begin
raise EArgumentNilException.Create('value');
end;
newValue := TIntX.Create(value);
if (newValue._length <> 0) then
begin
newValue._negative := not newValue._negative;
end;
result := newValue;
end;
class operator TIntX.Inc(value: TIntX): TIntX;
begin
// Exception
if TIntX.CompareRecords(value, Default (TIntX)) then
begin
raise EArgumentNilException.Create('value');
end;
result := value + UInt32(1);
end;
class operator TIntX.Dec(value: TIntX): TIntX;
begin
// Exception
if TIntX.CompareRecords(value, Default (TIntX)) then
begin
raise EArgumentNilException.Create('value');
end;
result := value - UInt32(1);
end;
class operator TIntX.BitwiseOr(int1: TIntX; int2: TIntX): TIntX;
begin
result := TOpHelper.BitwiseOr(int1, int2);
end;
class operator TIntX.BitwiseAnd(int1: TIntX; int2: TIntX): TIntX;
begin
result := TOpHelper.BitwiseAnd(int1, int2);
end;
class operator TIntX.BitwiseXor(int1: TIntX; int2: TIntX): TIntX;
begin
result := TOpHelper.ExclusiveOr(int1, int2);
end;
class operator TIntX.LogicalNot(value: TIntX): TIntX;
begin
result := TOpHelper.OnesComplement(value);
end;
class operator TIntX.Implicit(value: Byte): TIntX;
begin
result := TIntX.Create(value);
end;
class operator TIntX.Implicit(value: ShortInt): TIntX;
begin
result := TIntX.Create(value);
end;
class operator TIntX.Implicit(value: SmallInt): TIntX;
begin
result := TIntX.Create(value);
end;
class operator TIntX.Implicit(value: Word): TIntX;
begin
result := TIntX.Create(value);
end;
class operator TIntX.Implicit(value: Integer): TIntX;
begin
result := TIntX.Create(value);
end;
class operator TIntX.Implicit(value: UInt32): TIntX;
begin
result := TIntX.Create(value);
end;
class operator TIntX.Implicit(value: Int64): TIntX;
begin
result := TIntX.Create(value);
end;
class operator TIntX.Implicit(value: UInt64): TIntX;
begin
result := TIntX.Create(value);
end;
class operator TIntX.Explicit(value: Double): TIntX;
begin
result := TIntX.Create(value);
end;
{$OVERFLOWCHECKS ON}
class operator TIntX.Explicit(value: TIntX): Byte;
begin
result := Byte(Integer(value));
end;
{$OVERFLOWCHECKS OFF}
{$OVERFLOWCHECKS ON}
class operator TIntX.Explicit(value: TIntX): ShortInt;
begin
result := ShortInt(Integer(value));
end;
{$OVERFLOWCHECKS OFF}
{$OVERFLOWCHECKS ON}
class operator TIntX.Explicit(value: TIntX): SmallInt;
begin
result := SmallInt(Integer(value));
end;
{$OVERFLOWCHECKS OFF}
{$OVERFLOWCHECKS ON}
class operator TIntX.Explicit(value: TIntX): Word;
begin
result := Word(Integer(value));
end;
{$OVERFLOWCHECKS OFF}
class operator TIntX.Explicit(value: TIntX): Integer;
var
res: Integer;
begin
res := Integer(UInt32(value));
if value._negative then
result := -res
else
result := res
end;
class operator TIntX.Explicit(value: TIntX): UInt32;
begin
// Exception
if TIntX.CompareRecords(value, Default (TIntX)) then
raise EArgumentNilException.Create('value');
if (value._length = 0) then
begin
result := 0;
Exit;
end;
result := value._digits[0];
end;
class operator TIntX.Explicit(value: TIntX): Int64;
var
res: Int64;
begin
res := Int64(UInt64(value));
if value._negative then
result := -res
else
result := res
end;
class operator TIntX.Explicit(value: TIntX): UInt64;
var
res: UInt64;
begin
res := UInt32(value);
if (value._length > 1) then
begin
res := res or UInt64(value._digits[1]) shl TConstants.DigitBitCount;
end;
result := res;
end;
class operator TIntX.Explicit(value: TIntX): Double;
begin
result := value.AsDouble;
end;
class function TIntX.Multiply(int1: TIntX; int2: TIntX;
mode: TMultiplyMode): TIntX;
begin
result := TMultiplyManager.GetMultiplier(mode).Multiply(int1, int2);
end;
class function TIntX.Divide(int1: TIntX; int2: TIntX; mode: TDivideMode): TIntX;
var
modRes: TIntX;
begin
result := TDivideManager.GetDivider(mode).DivMod(int1, int2, modRes,
TDivModResultFlags.dmrfDiv);
end;
class function TIntX.Modulo(int1: TIntX; int2: TIntX; mode: TDivideMode): TIntX;
var
modRes: TIntX;
begin
TDivideManager.GetDivider(mode).DivMod(int1, int2, modRes,
TDivModResultFlags.dmrfMod);
result := modRes;
end;
class function TIntX.DivideModulo(int1: TIntX; int2: TIntX;
out modRes: TIntX): TIntX;
begin
result := TDivideManager.GetCurrentDivider().DivMod(int1, int2, modRes,
TDivModResultFlags(Ord(TDivModResultFlags.dmrfDiv) or
Ord(TDivModResultFlags.dmrfMod)));
end;
class function TIntX.DivideModulo(int1: TIntX; int2: TIntX; out modRes: TIntX;
mode: TDivideMode): TIntX;
begin
result := TDivideManager.GetDivider(mode).DivMod(int1, int2, modRes,
TDivModResultFlags(Ord(TDivModResultFlags.dmrfDiv) or
Ord(TDivModResultFlags.dmrfMod)));
end;
class function TIntX.Random(): TIntX;
begin
result := TOpHelper.Random();
end;
class function TIntX.RandomRange(Min: UInt32; Max: UInt32): TIntX;
begin
result := TOpHelper.RandomRange(Min, Max);
end;
class function TIntX.AbsoluteValue(value: TIntX): TIntX;
begin
// Exception
if CompareRecords(value, Default (TIntX)) then
raise EArgumentNilException.Create(uStrings.CantBeNull + ' value');
result := TOpHelper.AbsoluteValue(value);
end;
class function TIntX.Log10(value: TIntX): Double;
begin
// Exception
if CompareRecords(value, Default (TIntX)) then
raise EArgumentNilException.Create(uStrings.CantBeNull + ' value');
result := TOpHelper.Log10(value);
end;
class function TIntX.Ln(value: TIntX): Double;
begin
// Exception
if CompareRecords(value, Default (TIntX)) then
raise EArgumentNilException.Create(uStrings.CantBeNull + ' value');
result := TOpHelper.Ln(value);
end;
class function TIntX.LogN(base: Double; value: TIntX): Double;
begin
// Exception
if CompareRecords(value, Default (TIntX)) then
raise EArgumentNilException.Create(uStrings.CantBeNull + ' value');
result := TOpHelper.LogN(base, value);
end;
class function TIntX.IntegerLogN(base: TIntX; number: TIntX): TIntX;
begin
// Exceptions
if CompareRecords(base, Default (TIntX)) then
raise EArgumentNilException.Create(uStrings.CantBeNull + ' base');
if CompareRecords(number, Default (TIntX)) then
raise EArgumentNilException.Create(uStrings.CantBeNull + ' number');
if ((base = 0) or (number = 0)) then
raise EArgumentException.Create(uStrings.LogCantComputeZero);
if ((base._negative) or (number._negative)) then
raise EArgumentException.Create(uStrings.LogNegativeNotAllowed);
result := TOpHelper.IntegerLogN(base, number);
end;
class function TIntX.Square(value: TIntX): TIntX;
begin
// Exception
if TIntX.CompareRecords(value, Default (TIntX)) then
begin
raise EArgumentNilException.Create('value');
end;
result := TOpHelper.Square(value);
end;
class function TIntX.IntegerSquareRoot(value: TIntX): TIntX;
begin
// Exceptions
if TIntX.CompareRecords(value, Default (TIntX)) then
begin
raise EArgumentNilException.Create('value');
end;
if value._negative then
raise EArgumentException.Create(NegativeSquareRoot + ' value');
result := TOpHelper.IntegerSquareRoot(value);
end;
class function TIntX.Factorial(value: TIntX): TIntX;
begin
// Exception
if CompareRecords(value, Default (TIntX)) then
raise EArgumentNilException.Create(uStrings.CantBeNull + ' value');
result := TOpHelper.Factorial(value);
end;
class function TIntX.GCD(int1: TIntX; int2: TIntX): TIntX;
begin
// Exceptions
if TIntX.CompareRecords(int1, Default (TIntX)) then
raise EArgumentNilException.Create('int1');
if TIntX.CompareRecords(int2, Default (TIntX)) then
raise EArgumentNilException.Create('int2');
result := TOpHelper.GCD(int1, int2);
end;
class function TIntX.LCM(int1: TIntX; int2: TIntX): TIntX;
begin
// Exceptions
if TIntX.CompareRecords(int1, Default (TIntX)) then
raise EArgumentNilException.Create('int1');
if TIntX.CompareRecords(int2, Default (TIntX)) then
raise EArgumentNilException.Create('int2');
result := TOpHelper.LCM(int1, int2);
end;
class function TIntX.InvMod(int1: TIntX; int2: TIntX): TIntX;
begin
// Exceptions
if TIntX.CompareRecords(int1, Default (TIntX)) then
raise EArgumentNilException.Create('int1');
if TIntX.CompareRecords(int2, Default (TIntX)) then
raise EArgumentNilException.Create('int2');
if ((int1._negative) or (int2._negative)) then
raise EArgumentException.Create(uStrings.InvModNegativeNotAllowed);
result := TOpHelper.InvMod(int1, int2);
end;
class function TIntX.ModPow(value: TIntX; exponent: TIntX;
modulus: TIntX): TIntX;
begin
// Exceptions
if TIntX.CompareRecords(value, Default (TIntX)) then
raise EArgumentNilException.Create('value');
if TIntX.CompareRecords(exponent, Default (TIntX)) then
raise EArgumentNilException.Create('exponent');
if TIntX.CompareRecords(modulus, Default (TIntX)) then
raise EArgumentNilException.Create('modulus');
if modulus <= 0 then
raise EArgumentException.Create(uStrings.ModPowModulusCantbeZeroorNegative);
if (exponent._negative) then
raise EArgumentException.Create(uStrings.ModPowExponentCantbeNegative);
result := TOpHelper.ModPow(value, exponent, modulus);
end;
class function TIntX.Bezoutsidentity(int1: TIntX; int2: TIntX;
out bezOne: TIntX; out bezTwo: TIntX): TIntX;
begin
// Exceptions
if TIntX.CompareRecords(int1, Default (TIntX)) then
raise EArgumentNilException.Create('int1');
if TIntX.CompareRecords(int2, Default (TIntX)) then
raise EArgumentNilException.Create('int2');
result := TOpHelper.Bezoutsidentity(int1, int2, bezOne, bezTwo);
end;
class function TIntX.IsProbablyPrime(value: TIntX;
Accuracy: Integer = 5): Boolean;
begin
// Exception
if TIntX.CompareRecords(value, Default (TIntX)) then
raise EArgumentNilException.Create('value');
result := TOpHelper.IsProbablyPrime(value, Accuracy);
end;
class function TIntX.Max(left: TIntX; right: TIntX): TIntX;
begin
// Exceptions
if TIntX.CompareRecords(left, Default (TIntX)) then
raise EArgumentNilException.Create('left');
if TIntX.CompareRecords(right, Default (TIntX)) then
raise EArgumentNilException.Create('right');
result := TOpHelper.Max(left, right);
end;
class function TIntX.Min(left: TIntX; right: TIntX): TIntX;
begin
// Exceptions
if TIntX.CompareRecords(left, Default (TIntX)) then
raise EArgumentNilException.Create('left');
if TIntX.CompareRecords(right, Default (TIntX)) then
raise EArgumentNilException.Create('right');
result := TOpHelper.Min(left, right);
end;
class function TIntX.Pow(value: TIntX; power: UInt32): TIntX;
begin
result := TOpHelper.Pow(value, power, TIntX.GlobalSettings.multiplyMode);
end;
class function TIntX.Pow(value: TIntX; power: UInt32;
multiplyMode: TMultiplyMode): TIntX;
begin
result := TOpHelper.Pow(value, power, multiplyMode);
end;
function TIntX.ToString(): String;
begin
result := ToString(UInt32(10), true);
end;
function TIntX.ToString(numberBase: UInt32): String;
begin
result := ToString(numberBase, true);
end;
function TIntX.ToString(numberBase: UInt32; UpperCase: Boolean): String;
var
tempCharArray: TIntXLibCharArray;
begin
if UpperCase then
tempCharArray := TConstants.FBaseUpperChars
else
begin
tempCharArray := TConstants.FBaseLowerChars;
end;
result := TStringConvertManager.GetStringConverter(Settings.ToStringMode)
.ToString(Self, numberBase, tempCharArray);
end;
function TIntX.ToString(numberBase: UInt32; const alphabet: String): String;
begin
TStrRepHelper.AssertAlphabet(alphabet, numberBase);
result := TStringConvertManager.GetStringConverter(Settings.ToStringMode)
.ToString(Self, numberBase, TStrRepHelper.ToCharArray(alphabet));
end;
function TIntX.AsDouble: Double;
const
infinityLength = Integer(1024 div 32);
DoublePositiveInfinity: Double = 1.0 / 0.0;
DoubleNegativeInfinity: Double = -1.0 / 0.0;
var
man, h, m, l: UInt64;
exp, sign, lLength, z: Integer;
// reg: TOpHelper.TBuilder;
bits: TIntXLibUInt32Array;
begin
// Exception
if TIntX.CompareRecords(Self, Default (TIntX)) then
raise EArgumentNilException.Create('value');
// sign := 1;
// reg := TOpHelper.TBuilder.Create(Self, sign);
// reg.GetApproxParts(exp, man);
// result := TOpHelper.GetDoubleFromParts(sign, exp, man);
bits := Self._digits;
lLength := Self._length;
if Self.IsZero then
begin
result := 0;
Exit;
end;
if Self.IsNegative then
begin
sign := -1
end
else
begin
sign := 1;
end;
if (lLength > infinityLength) then
begin
if sign = 1 then
begin
result := DoublePositiveInfinity;
Exit;
end
else
begin
result := DoubleNegativeInfinity;
Exit;
end;
end;
h := bits[lLength - 1];
if lLength > 1 then
m := bits[lLength - 2]
else
m := 0;
if lLength > 2 then
l := bits[lLength - 3]
else
l := 0;
// measure the exact bit count
z := TOpHelper.CbitHighZero(UInt32(h));
exp := ((lLength - 2) * 32) - z;
// extract most significant bits
man := (h shl (32 + z)) or (m shl z) or (l shr (32 - z));
result := TOpHelper.GetDoubleFromParts(sign, exp, man);
end;
function TIntX.AsInteger: Integer;
var
res: Integer;
begin
// Exception
if TIntX.CompareRecords(Self, Default (TIntX)) then
raise EArgumentNilException.Create('value');
if (Self._length = 0) then
begin
result := 0;
Exit;
end;
if ((Self._length > 1) or (Self._digits[0] > UInt32(TConstants.MaxIntValue)))
then
raise EOverflowException.Create(uStrings.OverFlow_Data);
res := Integer(Self._digits[0]);
if Self._negative then
result := -res
else
result := res;
end;
function TIntX.AsUInt32: UInt32;
begin
// Exception
if TIntX.CompareRecords(Self, Default (TIntX)) then
raise EArgumentNilException.Create('value');
if (Self._length = 0) then
begin
result := 0;
Exit;
end;
if ((Self._length > 1) or (Self._negative)) then
raise EOverflowException.Create(uStrings.OverFlow_Data);
result := Self._digits[0];
end;
function TIntX.AsInt64: Int64;
var
res: UInt64;
begin
// Exception
if TIntX.CompareRecords(Self, Default (TIntX)) then
raise EArgumentNilException.Create('value');
if (Self._length = 0) then
begin
result := 0;
Exit;
end;
if (Self._length > 2) then
raise EOverflowException.Create(uStrings.OverFlow_Data);
res := Self._digits[0];
if (Self._length > 1) then
begin
res := res or (UInt64(Self._digits[1]) shl TConstants.DigitBitCount);
end;
{$WARNINGS OFF}
if res > (TConstants.MinInt64Value) then
begin
raise EOverflowException.Create(uStrings.OverFlow_Data);
end;
if ((res = TConstants.MinInt64Value) and (not Self._negative)) then
begin
raise EOverflowException.Create(uStrings.OverFlow_Data);
end;
{$WARNINGS ON}
if Self._negative then
result := -Int64(res)
else
result := Int64(res);
end;
function TIntX.AsUInt64: UInt64;
var
res: UInt64;
begin
// Exception
if TIntX.CompareRecords(Self, Default (TIntX)) then
raise EArgumentNilException.Create('value');
if (Self._length = 0) then
begin
result := 0;
Exit;
end;
if (((Self._length) > 2) or (Self._negative)) then
raise EOverflowException.Create(uStrings.OverFlow_Data);
res := Self._digits[0];
if (Self._length > 1) then
begin
res := res or (UInt64(Self._digits[1]) shl TConstants.DigitBitCount);
end;
result := res;
end;
class function TIntX.Parse(const value: String): TIntX;
begin
result := TParseManager.GetCurrentParser().Parse(value, UInt32(10),
TConstants.FBaseCharToDigits, true);
end;
class function TIntX.Parse(const value: String; numberBase: UInt32): TIntX;
begin
result := TParseManager.GetCurrentParser().Parse(value, numberBase,
TConstants.FBaseCharToDigits, false);
end;
class function TIntX.Parse(const value: String; numberBase: UInt32;
const alphabet: String): TIntX;
var
LCharDigits: TDictionary;
begin
LCharDigits := TStrRepHelper.CharDictionaryFromAlphabet(alphabet, numberBase);
try
result := TParseManager.GetCurrentParser().Parse(value, numberBase,
LCharDigits, false);
finally
LCharDigits.Free;
end;
end;
class function TIntX.Parse(const value: String; mode: TParseMode): TIntX;
begin
result := TParseManager.GetParser(mode).Parse(value, UInt32(10),
TConstants.FBaseCharToDigits, true);
end;
class function TIntX.Parse(const value: String; numberBase: UInt32;
mode: TParseMode): TIntX;
begin
result := TParseManager.GetParser(mode).Parse(value, numberBase,
TConstants.FBaseCharToDigits, false);
end;
class function TIntX.Parse(const value: String; numberBase: UInt32;
const alphabet: String; mode: TParseMode): TIntX;
var
LCharDigits: TDictionary;
begin
LCharDigits := TStrRepHelper.CharDictionaryFromAlphabet(alphabet, numberBase);
try
result := TParseManager.GetParser(mode).Parse(value, numberBase,
LCharDigits, false);
finally
LCharDigits.Free;
end;
end;
function TIntX.Equals(n: TIntX): Boolean;
begin
result := Self = n;
end;
function TIntX.Equals(n: Integer): Boolean;
begin
result := Self = n;
end;
function TIntX.Equals(n: UInt32): Boolean;
begin
result := Self = n;
end;
function TIntX.Equals(n: Int64): Boolean;
begin
result := Self = n;
end;
function TIntX.Equals(n: UInt64): Boolean;
begin
result := Self = n;
end;
function TIntX.CompareTo(n: TIntX): Integer;
begin
result := TOpHelper.Cmp(Self, n, true);
end;
function TIntX.CompareTo(n: Integer): Integer;
begin
result := TOpHelper.Cmp(Self, n);
end;
function TIntX.CompareTo(n: UInt32): Integer;
begin
result := TOpHelper.Cmp(Self, n);
end;
function TIntX.CompareTo(n: Int64): Integer;
begin
result := TOpHelper.Cmp(Self, n, true);
end;
function TIntX.CompareTo(n: UInt64): Integer;
begin
result := TOpHelper.Cmp(Self, n, true);
end;
procedure TIntX.Normalize();
var
newDigits: TIntXLibUInt32Array;
begin
if (UInt32(Length(_digits)) > _length) then
begin
SetLength(newDigits, _length);
Move(_digits[0], newDigits[0], _length * SizeOf(UInt32));
_digits := newDigits;
end;
if (_length = 0) then
begin
_negative := false;
end;
end;
procedure TIntX.GetInternalState(out digits: TIntXLibUInt32Array;
out negative: Boolean; out zeroinithelper: Boolean);
begin
SetLength(digits, _length);
Move(_digits[0], digits[0], _length * SizeOf(UInt32));
negative := _negative;
zeroinithelper := _zeroinithelper;
end;
procedure TIntX.InitFromZero();
begin
_length := 0;
SetLength(_digits, 0);
_zeroinithelper := true;
_negative := false;
end;
procedure TIntX.InitFromUlong(value: UInt64);
var
low, high: UInt32;
begin
// Divide uint64 into 2 uint32 values
low := UInt32(value);
high := UInt32(value shr TConstants.DigitBitCount);
// Prepare internal fields
if (high = 0) then
begin
SetLength(_digits, 1);
_digits[0] := low;
end
else
begin
SetLength(_digits, 2);
_digits[0] := low;
_digits[1] := high;
end;
_length := UInt32(Length(_digits));
end;
procedure TIntX.InitFromIntX(value: TIntX);
begin
_digits := value._digits;
_length := value._length;
_negative := value._negative;
_zeroinithelper := value._zeroinithelper;
end;
procedure TIntX.InitFromDigits(digits: TIntXLibUInt32Array; negative: Boolean;
mlength: UInt32);
begin
_length := mlength;
SetLength(_digits, _length);
Move(digits[0], _digits[0], mlength * SizeOf(UInt32));
if (mlength <> 0) then
begin
_negative := negative;
end;
end;
procedure TIntX.TryNormalize();
begin
if (Settings.AutoNormalize) then
begin
Normalize();
end;
end;
end.