{"id":31,"date":"2020-06-04T11:22:03","date_gmt":"2020-06-04T11:22:03","guid":{"rendered":"https:\/\/michaeljohnsteiner.com\/?p=31"},"modified":"2021-06-12T03:08:50","modified_gmt":"2021-06-12T03:08:50","slug":"fixedbiginteger-cs","status":"publish","type":"post","link":"https:\/\/michaeljohnsteiner.com\/index.php\/2020\/06\/04\/fixedbiginteger-cs\/","title":{"rendered":"(Obsolete) FixedBigInteger.cs"},"content":{"rendered":"\n<p><strong>Adjustable Fixed Bit Width Signed Integer 32,64,128,256,&#8230;<\/strong><\/p>\n\n\n\n<p>Jun-11,2021: Obsolete Use xIntX Instead.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.Numerics;\nusing System.Runtime.InteropServices;\nusing System.Runtime.Serialization;\nusing System.Text;\n[Serializable]\n[StructLayout(LayoutKind.Sequential, Pack = 1)]\n[TypeConverter(typeof(FixedBigIntegerConverter))]\n[DebuggerDisplay(\"{DDisplay}\")]\npublic class FixedBigInteger : IComparable&lt;FixedBigInteger>, IComparable, IEquatable&lt;FixedBigInteger>, IConvertible, IFormattable, ISerializable\n{\n    private const          int               DefaultDataBitWidth = 2048;\n    private const          int               DataSize            = sizeof(uint);\n    private const          int               DataShiftCount      = 5;\n    private const          uint              AllBits             = ~(uint) 0;\n    private const          int               DataSizeBits        = sizeof(uint) * 8;\n    private const          uint              HiNeg               = (uint) 1 &lt;&lt; (DataSizeBits - 1);\n    private static         int               DataBitWidth;\n    private static         int               DataLength;\n    public static readonly FixedBigInteger   One   = new FixedBigInteger(1,  DataBitWidth);\n    public static readonly FixedBigInteger   Two   = new FixedBigInteger(2,  DataBitWidth);\n    public static readonly FixedBigInteger   Zero  = new FixedBigInteger(0,  DataBitWidth);\n    public static readonly FixedBigInteger   Ten   = new FixedBigInteger(10, DataBitWidth);\n    public static readonly FixedBigInteger   Three = new FixedBigInteger(3,  DataBitWidth);\n    private readonly       SerializationInfo SInfo;\n    public                 uint[]            Data;\n    public FixedBigInteger(FixedBigInteger value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        CalculateMinDataLength(value.Data.Length);\n        Data = new uint[DataLength];\n        value.Data.CopyTo(Data, 0);\n    }\n    public FixedBigInteger(string value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        if (!TryParse(value, out var result))\n            throw new Exception(\"TryParse Failed.\");\n        CalculateMinDataLength(result.Data.Length);\n        Data = new uint[DataLength];\n        result.Data.CopyTo(Data, 0);\n    }\n    public FixedBigInteger(byte value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        if (bitLength &lt; 32)\n            bitLength = 32;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        Data         = new uint[DataLength];\n        Data[0]      = value;\n    }\n    public FixedBigInteger(bool value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        if (bitLength &lt; 32)\n            bitLength = 32;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        Data         = new uint[DataLength];\n        Data[0]      = (uint) (value ? 1 : 0);\n    }\n    public FixedBigInteger(char value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        if (bitLength &lt; 32)\n            bitLength = 32;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        Data         = new uint[DataLength];\n        Data[0]      = value;\n    }\n    public FixedBigInteger(BigDecimal value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        var ba = value.WholePart.ToByteArray();\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        var len = ba.Length \/ DataSize;\n        CalculateMinDataLength(len);\n        Data = new uint[DataLength];\n        for (var i = 0; i &lt; Data.Length; i++)\n            Data[i] = BitConverter.ToUInt32(ba, i * DataSize);\n    }\n    public FixedBigInteger(decimal value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        CalculateMinDataLength(3);\n        Data = new uint[DataLength];\n        if (value &lt; 0)\n        {\n            var n = -new FixedBigInteger(-value, DataBitWidth);\n            n.Data.CopyTo(Data, 0);\n            return;\n        }\n        var bits = decimal.GetBits(value);\n        Data[2] = (uint) bits[2];\n        Data[1] = (uint) bits[1];\n        Data[0] = (uint) bits[0];\n    }\n    public FixedBigInteger(double value, int bitLength = 0) : this((decimal) value, bitLength)\n    {\n    }\n    public FixedBigInteger(float value, int bitLength = 0) : this((decimal) value, bitLength)\n    {\n    }\n    public FixedBigInteger(short value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        if (bitLength &lt; 32)\n            bitLength = 32;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        Data         = new uint[DataLength];\n        if (value &lt; 0)\n        {\n            var n = -new FixedBigInteger(-(value + 1), DataBitWidth) - 1;\n            n.Data.CopyTo(Data, 0);\n            return;\n        }\n        Data[0] = (uint) value;\n    }\n    public FixedBigInteger()\n    {\n        DataBitWidth = DefaultDataBitWidth;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        Data         = new uint[DataLength];\n        Data[0]      = 0;\n    }\n    public FixedBigInteger(int value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        if (bitLength &lt; 32)\n            bitLength = 32;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        Data         = new uint[DataLength];\n        if (value &lt; 0)\n        {\n            var n = -new FixedBigInteger(-(value + 1), DataBitWidth) - 1;\n            n.Data.CopyTo(Data, 0);\n            return;\n        }\n        Data[0] = (uint) value;\n    }\n    public FixedBigInteger(long value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        if (bitLength &lt; 64)\n            bitLength = 64;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        Data         = new uint[DataLength];\n        if (value &lt; 0)\n        {\n            var n = -new FixedBigInteger(-(value + 1), DataBitWidth) - 1;\n            n.Data.CopyTo(Data, 0);\n            return;\n        }\n        Data[1] = (uint) ((value >> 32) &amp; 0xffffffff);\n        Data[0] = (uint) (value         &amp; 0xffffffff);\n    }\n    public FixedBigInteger(sbyte value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        if (bitLength &lt; 32)\n            bitLength = 32;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        Data         = new uint[DataLength];\n        if (value &lt; 0)\n        {\n            var n = -new FixedBigInteger(-(value + 1), DataBitWidth) - 1;\n            n.Data.CopyTo(Data, 0);\n            return;\n        }\n        Data[0] = (uint) value;\n    }\n    public FixedBigInteger(ushort value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        if (bitLength &lt; 32)\n            bitLength = 32;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        Data         = new uint[DataLength];\n        Data[0]      = value;\n    }\n    public FixedBigInteger(uint value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        if (bitLength &lt; 32)\n            bitLength = 32;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        Data         = new uint[DataLength];\n        Data[0]      = value;\n    }\n    public FixedBigInteger(ulong value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        if (bitLength &lt; 96)\n            bitLength = 96;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        Data         = new uint[DataLength];\n        Data[1]      = (uint) ((value >> 32) &amp; 0xffffffff);\n        Data[0]      = (uint) (value         &amp; 0xffffffff);\n    }\n    public FixedBigInteger(BigInteger value, int bitLength = 0) : this(value.ToByteArray(), bitLength)\n    {\n    }\n    public FixedBigInteger(Guid value, int bitLength = 0) : this(value.ToByteArray(), bitLength)\n    {\n    }\n    public FixedBigInteger(byte[] value, int bitLength = 0)\n    {\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        var minSize = value.Length \/ DataSize;\n        if (value == null)\n            throw new ArgumentNullException(\"value\");\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        CalculateMinDataLength(minSize);\n        var byteCount      = value.Length;\n        var isNegative     = byteCount > 0 &amp;&amp; (value[byteCount - 1] &amp; 0x80) == 0x80;\n        var unalignedBytes = byteCount % DataSize;\n        var dwordCount     = byteCount \/ DataSize + (unalignedBytes == 0 ? 0 : 1);\n        Data = new uint[Math.Max(dwordCount, DataLength)];\n        if (byteCount == 0)\n            return;\n        int curDword, curByte, byteInDword;\n        curByte = 3;\n        for (curDword = 0; curDword &lt; dwordCount - (unalignedBytes == 0 ? 0 : 1); curDword++)\n        {\n            byteInDword = 0;\n            while (byteInDword &lt; DataSize)\n            {\n                Data[curDword] &lt;&lt;= 8;\n                Data[curDword] |=  value[curByte];\n                curByte--;\n                byteInDword++;\n            }\n            curByte += 8;\n        }\n        if (unalignedBytes != 0)\n        {\n            if (isNegative)\n                Data[dwordCount - 1] = 0xffffffff;\n            for (curByte = byteCount - 1; curByte >= byteCount - unalignedBytes; curByte--)\n            {\n                Data[curDword] &lt;&lt;= 8;\n                Data[curDword] |=  value[curByte];\n            }\n        }\n    }\n    public FixedBigInteger(int sign, uint[] array, int bitLength = 0)\n    {\n        if (array == null)\n            throw new Exception(\"Array cannot be null.\");\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        CalculateMinDataLength(array.Length);\n        if (array.Length != DataLength)\n            Array.Resize(ref array, DataLength);\n        Data = new uint[DataLength];\n        var ba = new byte[DataSize];\n        for (var i = 0; i &lt; Data.Length; i++)\n        {\n            Array.Copy(BitConverter.GetBytes(array[i]), 0, ba, 0, DataSize);\n            Data[i] = BitConverter.ToUInt32(ba, 0);\n        }\n        if (sign &lt; 0)\n            Data[DataLength - 1] |= HiNeg;\n        else\n            Data[DataLength - 1] &amp;= ~HiNeg;\n    }\n    public FixedBigInteger(uint[] array, int bitLength = 0)\n    {\n        if (array == null)\n            throw new Exception(\"Array cannot be null.\");\n        if (bitLength == 0)\n            bitLength = DefaultDataBitWidth;\n        DataBitWidth = bitLength;\n        DataLength   = DataBitWidth >> DataShiftCount;\n        if (array.Length != DataLength)\n            Array.Resize(ref array, DataLength);\n        Data = new uint[DataLength];\n        var ba = new byte[DataSize];\n        for (var i = 0; i &lt; Data.Length; i++)\n        {\n            Array.Copy(BitConverter.GetBytes(array[i]), 0, ba, 0, DataSize);\n            Data[i] = BitConverter.ToUInt32(ba, 0);\n        }\n    }\n    protected FixedBigInteger(SerializationInfo info, StreamingContext context)\n    {\n        SInfo = info;\n    }\n    [DebuggerBrowsable(DebuggerBrowsableState.Never)]\n    private string DDisplay => ToString();\n    public FixedBigInteger MaxValue\n    {\n        get\n        {\n            var r = new FixedBigInteger(0, DataBitWidth);\n            for (var i = 0; i &lt; r.Data.Length; ++i)\n                r.Data[i] = uint.MaxValue;\n            r.Data[r.Data.Length - 1] = int.MaxValue;\n            return r;\n        }\n    }\n    public int BitWidth\n    {\n        get\n        {\n            FixedBigInteger bw = 1;\n            var             v  = new FixedBigInteger(this);\n            while ((v >>= 1) > 0)\n                bw++;\n            if (bw &lt; 8)\n                bw = 8;\n            while (bw % 8 != 0)\n                bw++;\n            return (int) bw;\n        }\n    }\n    public int Sign\n    {\n        get\n        {\n            var allZero = true;\n            var ba      = Data;\n            for (var i = 0; i &lt; ba.Length; i++)\n                if (ba[i] != 0)\n                {\n                    allZero = false;\n                    break;\n                }\n            if (allZero)\n                return 0;\n            return (Data[Data.Length - 1] &amp; HiNeg) == 0 ? 1 : -1;\n        }\n    }\n    public bool IsOne      => this       == 1;\n    public bool IsEven     => (this &amp; 1) == 0;\n    public bool IsNegative => Sign       &lt; 0;\n    public bool IsZero\n    {\n        get\n        {\n            for (var i = 0; i &lt; Data.Length; i++)\n                if (Data[i] != 0)\n                    return false;\n            return true;\n        }\n    }\n    public int DataUsed\n    {\n        get\n        {\n            var DataUsed = Data.Length;\n            if (!IsNegative)\n            {\n                while (DataUsed > 1 &amp;&amp; Data[DataUsed - 1] == 0)\n                    --DataUsed;\n                if (DataUsed == 0)\n                    DataUsed = 1;\n            }\n            return DataUsed;\n        }\n    }\n    int IComparable.CompareTo(object obj)\n    {\n        return Compare(this, obj);\n    }\n    public int CompareTo(FixedBigInteger value)\n    {\n        return Compare(this, value);\n    }\n    TypeCode IConvertible.GetTypeCode()\n    {\n        return TypeCode.Object;\n    }\n    bool IConvertible.ToBoolean(IFormatProvider provider)\n    {\n        return (bool) this;\n    }\n    byte IConvertible.ToByte(IFormatProvider provider)\n    {\n        return (byte) this;\n    }\n    char IConvertible.ToChar(IFormatProvider provider)\n    {\n        return (char) this;\n    }\n    DateTime IConvertible.ToDateTime(IFormatProvider provider)\n    {\n        throw new InvalidCastException();\n    }\n    decimal IConvertible.ToDecimal(IFormatProvider provider)\n    {\n        return (decimal) this;\n    }\n    double IConvertible.ToDouble(IFormatProvider provider)\n    {\n        return (double) this;\n    }\n    short IConvertible.ToInt16(IFormatProvider provider)\n    {\n        return (short) this;\n    }\n    int IConvertible.ToInt32(IFormatProvider provider)\n    {\n        return (int) this;\n    }\n    long IConvertible.ToInt64(IFormatProvider provider)\n    {\n        return (long) this;\n    }\n    sbyte IConvertible.ToSByte(IFormatProvider provider)\n    {\n        return (sbyte) this;\n    }\n    float IConvertible.ToSingle(IFormatProvider provider)\n    {\n        return (float) this;\n    }\n    string IConvertible.ToString(IFormatProvider provider)\n    {\n        return ToString(null, provider);\n    }\n    public object ToType(Type conversionType, IFormatProvider provider)\n    {\n        object value;\n        if (TryConvert(conversionType, provider, out value))\n            return value;\n        throw new InvalidCastException();\n    }\n    ushort IConvertible.ToUInt16(IFormatProvider provider)\n    {\n        if (Data[1] != 0)\n            throw new OverflowException();\n        return Convert.ToUInt16(Data[0]);\n    }\n    uint IConvertible.ToUInt32(IFormatProvider provider)\n    {\n        if (Data[1] != 0)\n            throw new OverflowException();\n        return Convert.ToUInt32(Data[0]);\n    }\n    ulong IConvertible.ToUInt64(IFormatProvider provider)\n    {\n        if (Data[1] != 0)\n            return ((ulong) Data[1] &lt;&lt; 32) | Data[0];\n        return Data[0];\n    }\n    public bool Equals(FixedBigInteger obj)\n    {\n        if (ReferenceEquals(obj, null))\n            return false;\n        if (ReferenceEquals(this, obj))\n            return true;\n        if (Data.Length != obj.Data.Length)\n        {\n            var len = Math.Max(Data.Length, obj.Data.Length);\n            if (Data.Length &lt; len)\n            {\n                var tData = new uint[len];\n                Array.Copy(Data, 0, tData, 0, Data.Length);\n                Data = tData;\n            }\n            if (obj.Data.Length &lt; len)\n                Resize(ref obj, len);\n        }\n        if (Sign != obj.Sign)\n            return false;\n        for (var i = 0; i &lt; Data.Length; i++)\n            if (Data[i] != obj.Data[i])\n                return false;\n        return true;\n    }\n    public string ToString(string format, IFormatProvider formatProvider)\n    {\n        if (formatProvider == null)\n            formatProvider = CultureInfo.CurrentCulture;\n        if (!string.IsNullOrEmpty(format))\n        {\n            var ch = format[0];\n            if (ch == 'x' || ch == 'X')\n            {\n                int.TryParse(format.Substring(1).Trim(), out var min);\n                return ToHexString(ch == 'X');\n            }\n            if (ch != 'G' &amp;&amp; ch != 'g' &amp;&amp; ch != 'D' &amp;&amp; ch != 'd')\n                throw new NotSupportedException(\"Not supported format: \" + format);\n        }\n        return ToString((NumberFormatInfo) formatProvider.GetFormat(typeof(NumberFormatInfo)), 10);\n    }\n    public void GetObjectData(SerializationInfo info, StreamingContext context)\n    {\n        info.AddValue(\"Bits\", DataBitWidth);\n        info.AddValue(\"Data\", Data, typeof(uint[]));\n    }\n    private static void CalculateMinDataLength(int minSize)\n    {\n        if (minSize > DataLength)\n        {\n            DataBitWidth = 32 * minSize;\n            DataLength   = minSize;\n        }\n    }\n    public void OnDeserialization(object sender)\n    {\n        if (SInfo == null)\n            return;\n        DataBitWidth = SInfo.GetInt32(\"Bits\");\n        if (DataBitWidth != 0)\n        {\n            DataLength = DataBitWidth >> DataShiftCount;\n            var array = (uint[]) SInfo.GetValue(\"Data\", typeof(uint[]));\n            if (array == null)\n                throw new Exception(\"Array cannot be null.\");\n            if (array.Length != DataLength)\n                Array.Resize(ref array, DataLength);\n            Data = new uint[DataLength];\n            var ba = new byte[4];\n            for (var i = 0; i &lt; DataLength; i++)\n            {\n                Array.Copy(BitConverter.GetBytes(array[i]), 0, ba, 0, DataSize);\n                Data[i] = BitConverter.ToUInt32(ba, 0);\n            }\n        }\n    }\n    public static int GetSign(uint[] value)\n    {\n        var allZero = true;\n        for (var i = 0; i &lt; value.Length; i++)\n            if (value[i] != 0)\n            {\n                allZero = false;\n                break;\n            }\n        if (allZero)\n            return 0;\n        return (value[value.Length - 1] &amp; HiNeg) == 0 ? 1 : -1;\n    }\n    private static int GetDataUsed(uint[] array)\n    {\n        var neg      = GetSign(array) &lt; 0;\n        var DataUsed = array.Length;\n        if (!neg)\n        {\n            while (DataUsed > 1 &amp;&amp; array[DataUsed - 1] == 0)\n                --DataUsed;\n            if (DataUsed == 0)\n                DataUsed = 1;\n        }\n        return DataUsed;\n    }\n    public int GetDecimalPlaces()\n    {\n        var dPlaces = 0;\n        if (Sign == 0)\n            return 1;\n        var a = new FixedBigInteger(this);\n        if (Sign &lt; 0)\n            try\n            {\n                a = -a;\n            }\n            catch (Exception ex)\n            {\n                return 0;\n            }\n        var biRadix = new FixedBigInteger(10, DataBitWidth);\n        while (a > 0)\n            try\n            {\n                Divide(a, biRadix, out var remainder, out var quotient);\n                a = quotient;\n                dPlaces++;\n            }\n            catch (Exception ex)\n            {\n                break;\n            }\n        return dPlaces;\n    }\n    private uint[] TwosComplement(uint[] d)\n    {\n        var  i = 0;\n        uint v = 0;\n        for (; i &lt; d.Length; i++)\n        {\n            v    = ~d[i] + 1;\n            d[i] = v;\n            if (v != 0)\n            {\n                i++;\n                break;\n            }\n        }\n        if (v != 0)\n        {\n            for (; i &lt; d.Length; i++)\n                d[i] = ~d[i];\n        }\n        else\n        {\n            Array.Resize(ref d, d.Length + 1);\n            d[d.Length - 1] = 1;\n        }\n        return d;\n    }\n    public void ConstructFromArray(byte[] array)\n    {\n        if (array == null)\n            throw new ArgumentNullException(\"value\");\n        var byteCount      = array.Length;\n        var isNegative     = byteCount > 0 &amp;&amp; (array[byteCount - 1] &amp; 0x80) == 0x80;\n        var unalignedBytes = byteCount % DataSize;\n        var dwordCount     = byteCount \/ DataSize + (unalignedBytes == 0 ? 0 : 1);\n        Data = new uint[Math.Max(dwordCount, DataLength)];\n        if (byteCount == 0)\n            return;\n        int curDword, curByte, byteInDword;\n        curByte = 3;\n        for (curDword = 0; curDword &lt; dwordCount - (unalignedBytes == 0 ? 0 : 1); curDword++)\n        {\n            byteInDword = 0;\n            while (byteInDword &lt; DataSize)\n            {\n                Data[curDword] &lt;&lt;= 8;\n                Data[curDword] |=  array[curByte];\n                curByte--;\n                byteInDword++;\n            }\n            curByte += 8;\n        }\n        if (unalignedBytes != 0)\n        {\n            if (isNegative)\n                Data[dwordCount - 1] = 0xffffffff;\n            for (curByte = byteCount - 1; curByte >= byteCount - unalignedBytes; curByte--)\n            {\n                Data[curDword] &lt;&lt;= 8;\n                Data[curDword] |=  array[curByte];\n            }\n        }\n    }\n    private static byte[] ToByteArray(ulong[] value)\n    {\n        var ba = new byte[value.Length &lt;&lt; 3];\n        Buffer.BlockCopy(value, 0, ba, 0, value.Length &lt;&lt; 3);\n        return ba;\n    }\n    private static byte[] ToByteArray(uint[] value)\n    {\n        var ba = new byte[value.Length &lt;&lt; 2];\n        Buffer.BlockCopy(value, 0, ba, 0, value.Length &lt;&lt; 2);\n        return ba;\n    }\n    public override int GetHashCode()\n    {\n        var hash = 0x811c9dc5;\n        for (var i = 0; i &lt; Data.Length; i++)\n        {\n            hash ^= ((hash &lt;&lt; 13) | (hash >> 19)) ^ Data[i];\n            hash *= 0x1000193;\n        }\n        return (int) hash;\n    }\n    public override bool Equals(object obj)\n    {\n        return base.Equals(obj);\n    }\n    public override string ToString()\n    {\n        return ToString(null, null);\n    }\n    public string ToString(string format)\n    {\n        return ToString(format, null);\n    }\n    public string ToHexString(bool caps)\n    {\n        var bytes = ToByteArray().Invert();\n        var sb    = new StringBuilder();\n        var x     = caps ? \"X\" : \"x\";\n        foreach (var b in bytes)\n        {\n            var hex = b.ToString($\"{x}2\");\n            sb.Append(hex);\n        }\n        return sb.ToString();\n    }\n    private string ToString(NumberFormatInfo info, int radix)\n    {\n        if (radix &lt; 2 || radix > 36)\n            throw new ArgumentOutOfRangeException(\"radix\");\n        if (Sign == 0)\n            return \"0\";\n        var negative = Sign &lt; 0;\n        var a        = new FixedBigInteger(this);\n        if (negative)\n            try\n            {\n                a = -a;\n            }\n            catch (Exception ex)\n            {\n            }\n        var          biRadix = new FixedBigInteger(radix, DataBitWidth);\n        const string charSet = \"0123456789abcdefghijklmnopqrstuvwxyz\";\n        var          al      = new ArrayList();\n        while (a > 0)\n            try\n            {\n                Divide(a, biRadix, out var remainder, out var quotient);\n                al.Insert(0, charSet[(int) remainder.Data[0]]);\n                a = quotient;\n            }\n            catch (Exception ex)\n            {\n                break;\n            }\n        var result = new string((char[]) al.ToArray(typeof(char)));\n        if (radix == 10 &amp;&amp; negative)\n            return \"-\" + result;\n        return result;\n    }\n    public static FixedBigInteger Abs(FixedBigInteger value)\n    {\n        if (ReferenceEquals(value, null))\n            throw new ArgumentNullException(\"value\");\n        if (value.Sign &lt; 0)\n            return -value;\n        return value;\n    }\n    public bool TryConvert(Type conversionType, IFormatProvider provider, out object value)\n    {\n        if (conversionType == typeof(bool))\n        {\n            value = (bool) this;\n            return true;\n        }\n        if (conversionType == typeof(byte))\n        {\n            value = (byte) this;\n            return true;\n        }\n        if (conversionType == typeof(char))\n        {\n            value = (char) this;\n            return true;\n        }\n        if (conversionType == typeof(decimal))\n        {\n            value = (decimal) this;\n            return true;\n        }\n        if (conversionType == typeof(double))\n        {\n            value = (double) this;\n            return true;\n        }\n        if (conversionType == typeof(short))\n        {\n            value = (short) this;\n            return true;\n        }\n        if (conversionType == typeof(int))\n        {\n            value = (int) this;\n            return true;\n        }\n        if (conversionType == typeof(long))\n        {\n            value = (long) this;\n            return true;\n        }\n        if (conversionType == typeof(sbyte))\n        {\n            value = (sbyte) this;\n            return true;\n        }\n        if (conversionType == typeof(float))\n        {\n            value = (float) this;\n            return true;\n        }\n        if (conversionType == typeof(string))\n        {\n            value = ToString(null, provider);\n            return true;\n        }\n        if (conversionType == typeof(ushort))\n        {\n            value = (ushort) this;\n            return true;\n        }\n        if (conversionType == typeof(uint))\n        {\n            value = (uint) this;\n            return true;\n        }\n        if (conversionType == typeof(ulong))\n        {\n            value = (ulong) this;\n            return true;\n        }\n        if (conversionType == typeof(byte[]))\n        {\n            value = ToByteArray();\n            return true;\n        }\n        if (conversionType == typeof(Guid))\n        {\n            value = new Guid(ToByteArray());\n            return true;\n        }\n        value = null;\n        return false;\n    }\n    public static FixedBigInteger Parse(string value)\n    {\n        return Parse(value, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);\n    }\n    public static FixedBigInteger Parse(string value, NumberStyles style)\n    {\n        return Parse(value, style, NumberFormatInfo.CurrentInfo);\n    }\n    public static FixedBigInteger Parse(string value, IFormatProvider provider)\n    {\n        return Parse(value, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));\n    }\n    public static FixedBigInteger Parse(string value, NumberStyles style, IFormatProvider provider)\n    {\n        if (!TryParse(value, style, provider, out var result))\n            throw new Exception($\"TryParse value {value} failure.\");\n        return result;\n    }\n    public static bool TryParse(string value, out FixedBigInteger result)\n    {\n        return TryParse(value, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);\n    }\n    public static bool TryParse(string value, NumberStyles style, IFormatProvider provider, out FixedBigInteger result)\n    {\n        result = 0;\n        if (string.IsNullOrEmpty(value))\n            return false;\n        if (value.StartsWith(\"x\", StringComparison.OrdinalIgnoreCase))\n        {\n            style |= NumberStyles.AllowHexSpecifier;\n            value =  value.Substring(1);\n        }\n        else\n        {\n            if (value.StartsWith(\"0x\", StringComparison.OrdinalIgnoreCase))\n            {\n                style |= NumberStyles.AllowHexSpecifier;\n                value =  value.Substring(2);\n            }\n        }\n        if ((style &amp; NumberStyles.AllowHexSpecifier) == NumberStyles.AllowHexSpecifier)\n            return TryParseNum(value, 16, out result);\n        return TryParseNum(value, 10, out result);\n    }\n    public static bool TryParseNum(string digits, int radix, out FixedBigInteger result)\n    {\n        result = new FixedBigInteger(0, DataBitWidth);\n        if (digits == null)\n            return false;\n        var multiplier = new FixedBigInteger(1, DataBitWidth);\n        digits = digits.ToUpper(CultureInfo.CurrentCulture).Trim();\n        var nDigits = digits[0] == '-' ? 1 : 0;\n        for (var idx = digits.Length - 1; idx >= nDigits; idx--)\n        {\n            var d = (int) digits[idx];\n            if (d >= '0' &amp;&amp; d &lt;= '9')\n                d -= '0';\n            else if (d >= 'A' &amp;&amp; d &lt;= 'Z')\n                d = d - 'A' + 10;\n            else\n                return false;\n            if (d >= radix)\n                return false;\n            result     += multiplier * d;\n            multiplier *= radix;\n        }\n        if (digits[0] == '-')\n            result = -result;\n        return true;\n    }\n    public static int Compare(FixedBigInteger left, object right)\n    {\n        if (right is FixedBigInteger)\n            return Compare(left, (FixedBigInteger) right);\n        if (right is bool)\n            return Compare(left, new FixedBigInteger((bool) right, DataBitWidth));\n        if (right is byte)\n            return Compare(left, new FixedBigInteger((byte) right, DataBitWidth));\n        if (right is char)\n            return Compare(left, new FixedBigInteger((char) right, DataBitWidth));\n        if (right is decimal)\n            return Compare(left, new FixedBigInteger((decimal) right, DataBitWidth));\n        if (right is double)\n            return Compare(left, new FixedBigInteger((double) right, DataBitWidth));\n        if (right is short)\n            return Compare(left, new FixedBigInteger((short) right, DataBitWidth));\n        if (right is int)\n            return Compare(left, new FixedBigInteger((int) right, DataBitWidth));\n        if (right is long)\n            return Compare(left, new FixedBigInteger((long) right, DataBitWidth));\n        if (right is sbyte)\n            return Compare(left, new FixedBigInteger((sbyte) right, DataBitWidth));\n        if (right is float)\n            return Compare(left, new FixedBigInteger((float) right, DataBitWidth));\n        if (right is ushort)\n            return Compare(left, new FixedBigInteger((ushort) right, DataBitWidth));\n        if (right is uint)\n            return Compare(left, new FixedBigInteger((uint) right, DataBitWidth));\n        if (right is ulong)\n            return Compare(left, new FixedBigInteger((ulong) right, DataBitWidth));\n        var bytes = right as byte[];\n        if (bytes != null)\n            return Compare(left, new FixedBigInteger(bytes, DataBitWidth));\n        if (right is Guid)\n            return Compare(left, new FixedBigInteger((Guid) right, DataBitWidth));\n        throw new ArgumentException();\n    }\n    public static int Compare(FixedBigInteger left, FixedBigInteger right)\n    {\n        MakeLikeLengths(ref left, ref right);\n        if (ReferenceEquals(left, right))\n            return 0;\n        if (left.Sign >= 0 &amp;&amp; right.Sign &lt; 0)\n            return 1;\n        if (left.Sign &lt; 0 &amp;&amp; right.Sign >= 0)\n            return -1;\n        for (var i = left.Data.Length - 1; i > 0; i--)\n            if (left.Data[i] != right.Data[i])\n                return left.Data[i].CompareTo(right.Data[i]);\n        return left.Data[0].CompareTo(right.Data[0]);\n    }\n    public static implicit operator FixedBigInteger(bool value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static implicit operator FixedBigInteger(byte value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static implicit operator FixedBigInteger(char value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static explicit operator FixedBigInteger(decimal value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static explicit operator FixedBigInteger(double value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static implicit operator FixedBigInteger(short value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static implicit operator FixedBigInteger(int value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static implicit operator FixedBigInteger(long value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static implicit operator FixedBigInteger(sbyte value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static explicit operator FixedBigInteger(float value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static implicit operator FixedBigInteger(ushort value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static implicit operator FixedBigInteger(uint value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static implicit operator FixedBigInteger(ulong value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static implicit operator FixedBigInteger(BigInteger value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static implicit operator FixedBigInteger(BigDecimal value)\n    {\n        return new FixedBigInteger(value, DataBitWidth);\n    }\n    public static explicit operator bool(FixedBigInteger value)\n    {\n        return (byte) value.Data[0] != 0;\n    }\n    public static explicit operator byte(FixedBigInteger value)\n    {\n        return (byte) value.Data[0];\n    }\n    public static explicit operator char(FixedBigInteger value)\n    {\n        return (char) (ushort) value.Data[0];\n    }\n    public static explicit operator decimal(FixedBigInteger value)\n    {\n        if (value.Sign == 0)\n            return 0;\n        if (value.Data.Length == 1)\n            return new decimal((int) value.Data[0], 0, 0, value.Sign &lt; 0, 0);\n        if (value.Data.Length == 2)\n            return new decimal((int) value.Data[0], (int) value.Data[1], 0, value.Sign &lt; 0, 0);\n        if (value.Data.Length == 3)\n            return new decimal((int) value.Data[0], (int) value.Data[1], (int) value.Data[2], value.Sign &lt; 0, 0);\n        throw new ArgumentException(\"Value length exceeds decimal length.\");\n    }\n    public static explicit operator double(FixedBigInteger value)\n    {\n        if (value.Sign == 0)\n            return 0;\n        var nfi = CultureInfo.InvariantCulture.NumberFormat;\n        if (!double.TryParse(value.ToString(nfi, 10), NumberStyles.Number, nfi, out var d))\n            throw new OverflowException();\n        return d;\n    }\n    public static explicit operator float(FixedBigInteger value)\n    {\n        if (value.Sign == 0)\n            return 0;\n        var nfi = CultureInfo.InvariantCulture.NumberFormat;\n        if (!float.TryParse(value.ToString(nfi, 10), NumberStyles.Number, nfi, out var f))\n            throw new OverflowException();\n        return f;\n    }\n    public static explicit operator short(FixedBigInteger value)\n    {\n        if (value.Data[0] > 0x8000)\n            throw new OverflowException();\n        if (value.Data[0] == 0x8000 &amp;&amp; value.Sign > 0)\n            throw new OverflowException();\n        return (short) ((int) value.Data[0] * value.Sign);\n    }\n    public static explicit operator int(FixedBigInteger value)\n    {\n        if (value.Sign == 0)\n            return 0;\n        return (int) value.Data[0] * value.Sign;\n    }\n    public static explicit operator long(FixedBigInteger value)\n    {\n        if (value.Sign == 0)\n            return 0;\n        if (value.Data[0] > int.MaxValue)\n            throw new OverflowException();\n        if (value.Data.Length > 1)\n            if (value.Data[1] != 0)\n                return (long) (((ulong) value.Data[1] &lt;&lt; 32) | value.Data[0]) * value.Sign;\n        return value.Data[0] * value.Sign;\n    }\n    public static explicit operator uint(FixedBigInteger value)\n    {\n        if (value.Sign == 0)\n            return 0;\n        return value.Data[0];\n    }\n    public static explicit operator ushort(FixedBigInteger value)\n    {\n        if (value.Sign == 0)\n            return 0;\n        return (ushort) value.Data[0];\n    }\n    public static explicit operator ulong(FixedBigInteger value)\n    {\n        if (value.Data.Length > 1)\n            if (value.Data[1] != 0)\n                return ((ulong) value.Data[1] &lt;&lt; 32) | value.Data[0];\n        return value.Data[0];\n    }\n    public static explicit operator BigInteger(FixedBigInteger value)\n    {\n        return new BigInteger(value.ToByteArray());\n    }\n    public static bool operator >(FixedBigInteger left, FixedBigInteger right)\n    {\n        return left.CompareTo(right) > 0;\n    }\n    private static void MakeLikeLengths(ref FixedBigInteger left, ref FixedBigInteger right)\n    {\n        if (left.Data.Length != right.Data.Length)\n        {\n            var len = Math.Max(left.Data.Length, right.Data.Length);\n            Resize(ref left,  len);\n            Resize(ref right, len);\n        }\n    }\n    private static void Resize(ref FixedBigInteger value, int newSize)\n    {\n        var IsNeg = value.IsNegative;\n        var nData = new uint[newSize];\n        var len   = value.Data.Length;\n        for (var i = 0; i &lt; len; i++)\n        {\n            nData[i] = value.Data[i];\n            if (IsNeg &amp;&amp; i == len - 1)\n                nData[i] &amp;= ~HiNeg;\n        }\n        if (IsNeg)\n            nData[nData.Length - 1] |= HiNeg;\n        value.Data = (uint[]) nData.Clone();\n    }\n    public static bool operator &lt;(FixedBigInteger left, FixedBigInteger right)\n    {\n        return Compare(left, right) &lt; 0;\n    }\n    public static bool operator >=(FixedBigInteger left, FixedBigInteger right)\n    {\n        return Compare(left, right) >= 0;\n    }\n    public static bool operator &lt;=(FixedBigInteger left, FixedBigInteger right)\n    {\n        return Compare(left, right) &lt;= 0;\n    }\n    public static bool operator !=(FixedBigInteger left, FixedBigInteger right)\n    {\n        return !left.Equals(right);\n    }\n    public static bool operator ==(FixedBigInteger left, FixedBigInteger right)\n    {\n        return left.Equals(right);\n    }\n    public static FixedBigInteger operator +(FixedBigInteger value)\n    {\n        return value;\n    }\n    public static FixedBigInteger operator ~(FixedBigInteger value)\n    {\n        var da = new uint[DataLength];\n        for (var idx = 0; idx &lt; DataLength; idx++)\n            da[idx] = ~value.Data[idx];\n        return new FixedBigInteger(da, DataBitWidth);\n    }\n    public static FixedBigInteger operator -(FixedBigInteger value)\n    {\n        if (ReferenceEquals(value, null))\n            throw new ArgumentNullException(\"value\");\n        if (value.IsZero)\n            return Zero;\n        var da = new uint[DataLength];\n        for (var i = 0; i &lt; da.Length; i++)\n            da[i] = ~value.Data[i];\n        var carry = true;\n        var index = 0;\n        while (carry &amp;&amp; index &lt; da.Length)\n        {\n            var val = (long) da[index] + 1;\n            da[index] = (uint) (val &amp; AllBits);\n            carry     = val >> DataSizeBits > 0;\n            index++;\n        }\n        return new FixedBigInteger(da, DataBitWidth);\n    }\n    public static FixedBigInteger operator ++(FixedBigInteger value)\n    {\n        return value + 1;\n    }\n    public static FixedBigInteger operator --(FixedBigInteger value)\n    {\n        return value - 1;\n    }\n    public static FixedBigInteger Negate(FixedBigInteger value)\n    {\n        var ldata = (uint[]) value.Data.Clone();\n        for (var i = 0; i &lt; value.Data.Length; i++)\n            ldata[i] = ~value.Data[i];\n        return new FixedBigInteger(value.Sign, ldata, DataBitWidth);\n    }\n    public static FixedBigInteger operator +(FixedBigInteger left, FixedBigInteger right)\n    {\n        if (right.IsZero)\n            return left;\n        if (left.IsZero)\n            return right;\n        MakeLikeLengths(ref left, ref right);\n        var  dl     = left.Data.Length > right.Data.Length ? left.Data.Length : right.Data.Length;\n        var  result = new uint[dl];\n        long carry  = 0;\n        for (var i = 0; i &lt; dl; i++)\n        {\n            var sum = left.Data[i] + (long) right.Data[i] + carry;\n            carry     = sum >> 32;\n            result[i] = (uint) (sum &amp; 0xFFFFFFFF);\n        }\n        if (carry != 0)\n        {\n            var idx = 0;\n            while (idx &lt; result.Length - 1)\n            {\n                if (result[idx] == 0)\n                    break;\n                idx++;\n            }\n            result[idx] = (uint) carry;\n        }\n        return new FixedBigInteger(left.Sign * right.Sign, result, DataBitWidth);\n    }\n    public static FixedBigInteger operator -(FixedBigInteger left, FixedBigInteger right)\n    {\n        if (right.IsZero)\n            return left;\n        if (left.IsZero)\n            return -right;\n        MakeLikeLengths(ref left, ref right);\n        var  da    = new uint[DataLength];\n        long carry = 0;\n        for (var i = 0; i &lt; DataLength &amp;&amp; i &lt; left.Data.Length &amp;&amp; i &lt; right.Data.Length; i++)\n        {\n            var diff = left.Data[i] - (long) right.Data[i] - carry;\n            da[i] = (uint) (diff &amp; AllBits);\n            carry = diff &lt; 0 ? 1 : 0;\n        }\n        return new FixedBigInteger(da, DataBitWidth);\n    }\n    public static FixedBigInteger Add(FixedBigInteger left, FixedBigInteger right)\n    {\n        return left + right;\n    }\n    public static FixedBigInteger Subtract(FixedBigInteger left, FixedBigInteger right)\n    {\n        return left - right;\n    }\n    public static FixedBigInteger Divide(FixedBigInteger dividend, FixedBigInteger divisor)\n    {\n        if (divisor == 0)\n            throw new DivideByZeroException();\n        return DivRem(dividend, divisor, out var integer);\n    }\n    public static void Divide(FixedBigInteger dividend, FixedBigInteger divisor, out FixedBigInteger remainder, out FixedBigInteger quotient)\n    {\n        if (divisor == 0)\n            throw new DivideByZeroException();\n        DivRem(dividend.Data, divisor.Data, out var quo, out var rem);\n        remainder = new FixedBigInteger(1,                            rem, DataBitWidth);\n        quotient  = new FixedBigInteger(dividend.Sign * divisor.Sign, quo, DataBitWidth);\n    }\n    public static FixedBigInteger DivRem(FixedBigInteger dividend, FixedBigInteger divisor, out FixedBigInteger remainder)\n    {\n        if (divisor == 0)\n            throw new DivideByZeroException();\n        DivRem(dividend.Data, divisor.Data, out var quotient, out var rem);\n        remainder = new FixedBigInteger(1, rem, DataBitWidth);\n        return new FixedBigInteger(dividend.Sign * divisor.Sign, quotient, DataBitWidth);\n    }\n    private static void DivRem(uint[] dividend, uint[] divisor, out uint[] quotient, out uint[] remainder)\n    {\n        const ulong hiBit       = 0x100000000;\n        var         divisorLen  = GetLength(divisor);\n        var         dividendLen = GetLength(dividend);\n        if (divisorLen &lt;= 1)\n        {\n            ulong rem = 0;\n            var   div = divisor[0];\n            quotient  = new uint[dividendLen];\n            remainder = new uint[1];\n            for (var i = dividendLen - 1; i >= 0; i--)\n            {\n                rem *= hiBit;\n                rem += dividend[i];\n                var q = rem \/ div;\n                rem         -= q * div;\n                quotient[i] =  (uint) q;\n            }\n            remainder[0] = (uint) rem;\n            return;\n        }\n        if (dividendLen >= divisorLen)\n        {\n            var shift        = GetNormalizeShift(divisor[divisorLen - 1]);\n            var normDividend = new uint[dividendLen + 1];\n            var normDivisor  = new uint[divisorLen];\n            Normalize(dividend, dividendLen, normDividend, shift);\n            Normalize(divisor,  divisorLen,  normDivisor,  shift);\n            quotient = new uint[dividendLen - divisorLen + 1];\n            for (var j = dividendLen - divisorLen; j >= 0; j--)\n            {\n                var dx = hiBit * normDividend[j + divisorLen] + normDividend[j + divisorLen - 1];\n                var qj = dx \/ normDivisor[divisorLen                                        - 1];\n                dx -= qj * normDivisor[divisorLen - 1];\n                do\n                {\n                    if (qj &lt; hiBit &amp;&amp; qj * normDivisor[divisorLen - 2] &lt;= dx * hiBit + normDividend[j + divisorLen - 2])\n                        break;\n                    qj -= 1L;\n                    dx += normDivisor[divisorLen - 1];\n                } while (dx &lt; hiBit);\n                ulong di = 0;\n                ulong dj;\n                var   index = 0;\n                while (index &lt; divisorLen)\n                {\n                    var dqj = normDivisor[index] * qj;\n                    dj                      = normDividend[index + j] - (uint) dqj - di;\n                    normDividend[index + j] = (uint) dj;\n                    dqj                     = dqj >> 32;\n                    dj                      = dj  >> 32;\n                    di                      = dqj - dj;\n                    index++;\n                }\n                dj                           = normDividend[j + divisorLen] - di;\n                normDividend[j + divisorLen] = (uint) dj;\n                quotient[j]                  = (uint) qj;\n                if ((long) dj &lt; 0)\n                {\n                    quotient[j]--;\n                    ulong sum = 0;\n                    for (index = 0; index &lt; divisorLen; index++)\n                    {\n                        sum                     = normDivisor[index] + normDividend[j + index] + sum;\n                        normDividend[j + index] = (uint) sum;\n                        sum                     = sum >> 32;\n                    }\n                    sum += normDividend[j + divisorLen];\n                    normDividend[j        + divisorLen] = (uint) sum;\n                }\n            }\n            remainder = Unnormalize(normDividend, shift);\n            return;\n        }\n        quotient  = new uint[1];\n        remainder = dividend;\n    }\n    private static int GetLength(uint[] uints)\n    {\n        var index = uints.Length - 1;\n        while (index >= 0 &amp;&amp; uints[index] == 0)\n            index--;\n        return index + 1;\n    }\n    private static int GetNormalizeShift(uint ui)\n    {\n        var shift = 0;\n        if ((ui &amp; 0xffff0000) == 0)\n        {\n            ui    =  ui &lt;&lt; 16;\n            shift += 16;\n        }\n        if ((ui &amp; 0xff000000) == 0)\n        {\n            ui    =  ui &lt;&lt; 8;\n            shift += 8;\n        }\n        if ((ui &amp; 0xf0000000) == 0)\n        {\n            ui    =  ui &lt;&lt; 4;\n            shift += 4;\n        }\n        if ((ui &amp; 0xc0000000) == 0)\n        {\n            ui    =  ui &lt;&lt; 2;\n            shift += 2;\n        }\n        if ((ui &amp; 0x80000000) == 0)\n            shift++;\n        return shift;\n    }\n    private static uint[] Unnormalize(uint[] normalized, int shift)\n    {\n        var len          = GetLength(normalized);\n        var unnormalized = new uint[len];\n        if (shift > 0)\n        {\n            var  rshift = 32 - shift;\n            uint r      = 0;\n            for (var i = len - 1; i >= 0; i--)\n            {\n                unnormalized[i] = (normalized[i] >> shift) | r;\n                r               = normalized[i] &lt;&lt; rshift;\n            }\n        }\n        else\n        {\n            for (var j = 0; j &lt; len; j++)\n                unnormalized[j] = normalized[j];\n        }\n        return unnormalized;\n    }\n    private static void Normalize(uint[] unormalized, int len, uint[] normalized, int shift)\n    {\n        int  i;\n        uint n = 0;\n        if (shift > 0)\n        {\n            var rShift = 32 - shift;\n            for (i = 0; i &lt; len; i++)\n            {\n                normalized[i] = (unormalized[i] &lt;&lt; shift) | n;\n                n             = unormalized[i] >> rShift;\n            }\n        }\n        else\n        {\n            i = 0;\n            while (i &lt; len)\n            {\n                normalized[i] = unormalized[i];\n                i++;\n            }\n        }\n        while (i &lt; normalized.Length)\n            normalized[i++] = 0;\n        if (n != 0)\n            normalized[len] = n;\n    }\n    public static FixedBigInteger Remainder(FixedBigInteger dividend, FixedBigInteger divisor)\n    {\n        DivRem(dividend, divisor, out var remainder);\n        return remainder;\n    }\n    public static FixedBigInteger Max(FixedBigInteger left, FixedBigInteger right)\n    {\n        return left.CompareTo(right) &lt; 0 ? right : left;\n    }\n    public static FixedBigInteger Min(FixedBigInteger left, FixedBigInteger right)\n    {\n        return left.CompareTo(right) &lt;= 0 ? left : right;\n    }\n    public static int GetBitWidth(FixedBigInteger n)\n    {\n        FixedBigInteger bw = 1;\n        var             v  = n;\n        while ((v >>= 1) > 0)\n            bw++;\n        if (bw &lt; 8)\n            bw = 8;\n        while (bw % 8 != 0)\n            bw++;\n        return (int) bw;\n    }\n    public static int GetBitWidth&lt;T>(T n)\n    {\n        ulong   bw = 1;\n        dynamic v  = new FixedBigInteger((dynamic) n, 0);\n        while ((v >>= 1) > 0)\n            bw++;\n        if (bw &lt; 8)\n            bw = 8;\n        while (bw % 8 != 0)\n            bw++;\n        return (int) bw;\n    }\n    public static FixedBigInteger operator %(FixedBigInteger dividend, FixedBigInteger divisor)\n    {\n        return Remainder(dividend, divisor);\n    }\n    public static FixedBigInteger operator \/(FixedBigInteger dividend, FixedBigInteger divisor)\n    {\n        return Divide(dividend, divisor);\n    }\n    public ulong[] ToUIn64Array()\n    {\n        var al = Data.Length >> 1;\n        if (al * 2 != Data.Length)\n            al++;\n        var arr = new ulong[al];\n        Buffer.BlockCopy(Data, 0, arr, 0, Data.Length &lt;&lt; 2);\n        return arr;\n    }\n    public uint[] ToUIn32Array()\n    {\n        return Data;\n    }\n    public byte[] ToByteArray()\n    {\n        var ba = new byte[DataUsed * DataSize];\n        Buffer.BlockCopy(Data, 0, ba, 0, DataUsed * DataSize);\n        return ba;\n    }\n    private void TrimToMsb()\n    {\n        var dataUsed = Data.Length;\n        while (dataUsed > 1 &amp;&amp; Data[dataUsed - 1] == 0)\n            --dataUsed;\n        if (dataUsed != Data.Length)\n        {\n            var tData = new uint[dataUsed];\n            for (var i = 0; i &lt; dataUsed; i++)\n                tData[i] = Data[i];\n            Data = (uint[]) tData.Clone();\n        }\n    }\n    public static FixedBigInteger Multiply(FixedBigInteger left, FixedBigInteger right)\n    {\n        if (left == 0 || right == 0)\n            return Zero;\n        if (left == 1 &amp;&amp; right != 1)\n            return right;\n        if (left != 1 &amp;&amp; right == 1)\n            return left;\n        if (left == 1 &amp;&amp; right == 1)\n            return One;\n        var xInts   = left.Data;\n        var yInts   = right.Data;\n        var mulInts = new uint[Math.Max(xInts.Length, yInts.Length) &lt;&lt; 1];\n        for (var i = 0; i &lt; xInts.Length; i++)\n        {\n            var   index     = i;\n            ulong remainder = 0;\n            foreach (var yi in yInts)\n            {\n                remainder        = remainder + (ulong) xInts[i] * yi + mulInts[index];\n                mulInts[index++] = (uint) remainder;\n                remainder        = remainder >> 32;\n            }\n            while (remainder != 0)\n            {\n                remainder        += mulInts[index];\n                mulInts[index++] =  (uint) remainder;\n                remainder        =  remainder >> 32;\n            }\n        }\n        var du = GetDataUsed(mulInts);\n        Array.Resize(ref mulInts, du);\n        return new FixedBigInteger(left.Sign * right.Sign, mulInts);\n    }\n    public static FixedBigInteger operator *(FixedBigInteger left, FixedBigInteger right)\n    {\n        return Multiply(left, right);\n    }\n    public static FixedBigInteger operator >>(FixedBigInteger value, int shift)\n    {\n        if (shift == 0)\n            return value;\n        if (shift == int.MinValue)\n            return value &lt;&lt; int.MaxValue &lt;&lt; 1;\n        if (shift &lt; 0)\n            return value &lt;&lt; -shift;\n        var xd          = value.Data;\n        var shiftAmount = 32;\n        var invShift    = 0;\n        var bufLen      = xd.Length;\n        while (bufLen > 1 &amp;&amp; xd[bufLen - 1] == 0)\n            bufLen--;\n        for (var count = shift; count > 0; count -= shiftAmount)\n        {\n            if (count &lt; shiftAmount)\n            {\n                shiftAmount = count;\n                invShift    = 32 - shiftAmount;\n            }\n            ulong carry = 0;\n            for (var i = bufLen - 1; i >= 0; i--)\n            {\n                var val = (ulong) xd[i] >> shiftAmount;\n                val   |= carry;\n                carry =  (ulong) xd[i] &lt;&lt; invShift;\n                xd[i] =  (uint) val;\n            }\n        }\n        return new FixedBigInteger(value.Sign, xd, DataBitWidth);\n    }\n    public static FixedBigInteger operator &lt;&lt;(FixedBigInteger value, int shift)\n    {\n        if (shift == 0)\n            return value;\n        if (shift == int.MinValue)\n            return value >> int.MaxValue >> 1;\n        if (shift &lt; 0)\n            return value >> -shift;\n        var digitShift = shift \/ 32;\n        var smallShift = shift - digitShift * 32;\n        var xd         = value.Data;\n        var xl         = xd.Length;\n        var zd         = new uint[xl + digitShift + 1];\n        if (smallShift == 0)\n        {\n            for (var index = 0; index &lt; xl; ++index)\n                zd[index + digitShift] = xd[index];\n        }\n        else\n        {\n            var  carryShift = 32 - smallShift;\n            uint carry      = 0;\n            int  index;\n            for (index = 0; index &lt; xl; ++index)\n            {\n                var rot = xd[index];\n                zd[index + digitShift] = (rot &lt;&lt; smallShift) | carry;\n                carry                  = rot >> carryShift;\n            }\n            zd[index + digitShift] = carry;\n        }\n        return new FixedBigInteger(value.Sign, zd, DataBitWidth);\n    }\n    public static FixedBigInteger operator |(FixedBigInteger left, FixedBigInteger right)\n    {\n        if (left == 0)\n            return right;\n        if (right == 0)\n            return left;\n        var z    = new uint[Math.Max(left.Data.Length, right.Data.Length)];\n        var lExt = left.Sign  &lt; 0 ? uint.MaxValue : 0U;\n        var rExt = right.Sign &lt; 0 ? uint.MaxValue : 0U;\n        for (var i = 0; i &lt; z.Length; i++)\n        {\n            var xu = i &lt; left.Data.Length ? left.Data[i] : lExt;\n            var yu = i &lt; right.Data.Length ? right.Data[i] : rExt;\n            z[i] = xu | yu;\n        }\n        return new FixedBigInteger(left.Sign * right.Sign, z, DataBitWidth);\n    }\n    public static FixedBigInteger operator ^(FixedBigInteger left, FixedBigInteger right)\n    {\n        var z    = new uint[Math.Max(left.Data.Length, right.Data.Length)];\n        var lExt = left.Sign  &lt; 0 ? uint.MaxValue : 0U;\n        var rExt = right.Sign &lt; 0 ? uint.MaxValue : 0U;\n        for (var i = 0; i &lt; z.Length; i++)\n        {\n            var xu = i &lt; left.Data.Length ? left.Data[i] : lExt;\n            var yu = i &lt; right.Data.Length ? right.Data[i] : rExt;\n            z[i] = xu ^ yu;\n        }\n        return new FixedBigInteger(left.Sign * right.Sign, z, DataBitWidth);\n    }\n    public static FixedBigInteger operator &amp;(FixedBigInteger left, FixedBigInteger right)\n    {\n        if (left == 0 || right == 0)\n            return 0;\n        var z    = new uint[Math.Max(left.Data.Length, right.Data.Length)];\n        var lExt = left.Sign  &lt; 0 ? uint.MaxValue : 0U;\n        var rExt = right.Sign &lt; 0 ? uint.MaxValue : 0U;\n        for (var i = 0; i &lt; z.Length; i++)\n        {\n            var xu = i &lt; left.Data.Length ? left.Data[i] : lExt;\n            var yu = i &lt; right.Data.Length ? right.Data[i] : rExt;\n            z[i] = xu &amp; yu;\n        }\n        return new FixedBigInteger(left.Sign * right.Sign, z, DataBitWidth);\n    }\n    public FixedBigInteger Sqrt()\n    {\n        var n     = this;\n        var q     = One &lt;&lt; ((int) Math.Ceiling(Log(n, 2)) >> 1);\n        var steps = 0;\n        var m     = Zero;\n        while (Abs(q - m) >= 1)\n        {\n            m = q;\n            q = (m + n \/ m) >> 1;\n            steps++;\n        }\n        return q;\n    }\n    public FixedBigInteger Pow(int e)\n    {\n        var ans = this;\n        if (e == 1)\n            return ans;\n        if (e == 0)\n            return 1;\n        for (var i = 1; i != e; i++)\n            ans *= this;\n        return ans;\n    }\n    public static FixedBigInteger ModPow(FixedBigInteger n, FixedBigInteger e, FixedBigInteger m)\n    {\n        var n1 = new BigIntX(n);\n        var e1 = new BigIntX(e);\n        var m1 = new BigIntX(m);\n        var r  = new BigIntX(1);\n        while (e1 != 0)\n        {\n            if (e1 % 2 == 1)\n                r = r * n1 % m1;\n            e1 >>= 1;\n            n1 =   n1 * n1 % m1;\n        }\n        return new FixedBigInteger(r.ToByteArray(), DataBitWidth);\n    }\n    public bool Fermat(FixedBigInteger candidate)\n    {\n        uint[] wits = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41};\n        var    pmo  = candidate - 1;\n        for (var i = 0; i &lt; wits.Length; i++)\n        {\n            var r = ModPow(wits[i], pmo, candidate);\n            if (r != One)\n                return false;\n        }\n        return true;\n    }\n    private static bool MillerRabin(FixedBigInteger candidate)\n    {\n        uint[] w = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41};\n        var    s = 0;\n        var    d = candidate - One;\n        while ((d &amp; 1) == 0)\n        {\n            d >>= 1;\n            ++s;\n        }\n        if (s == 0)\n            return false;\n        var nmo = candidate - One;\n        for (var i = 0; i &lt; w.Length; ++i)\n        {\n            var x = ModPow(w[i], nmo, candidate);\n            if (!(x == 1) &amp;&amp; !(x == nmo))\n            {\n                for (var r = 1; r &lt; s; ++r)\n                {\n                    x = ModPow(x, 2, candidate);\n                    if (x == 1)\n                        return false;\n                    if (x == nmo)\n                        break;\n                }\n                if (!(x == nmo))\n                    return false;\n            }\n        }\n        return true;\n    }\n    public bool IsPrime()\n    {\n        return MillerRabin(this);\n    }\n    public static double Log(FixedBigInteger value, double baseValue)\n    {\n        var c = 0.0;\n        var d = 0.5;\n        \/\/var dataLength = Length(value.Data);\n        var dataLength = value.Data[value.Data.Length - 1] != 0U ? value.Data.Length : value.Data.Length - 1;\n        var topBits    = 0; \/\/BitLengthOfUInt(value.Data[dataLength - 1]);\n        var x          = value.Data[dataLength - 1];\n        while (x > 0)\n        {\n            x >>= 1;\n            topBits++;\n        }\n        var bitLength = (dataLength - 1) * 32 + topBits;\n        var bit       = (uint) (1 &lt;&lt; (topBits - 1));\n        for (var index = dataLength - 1; index >= 0; --index)\n        {\n            for (; bit != 0U; bit >>= 1)\n            {\n                if (((int) value.Data[index] &amp; (int) bit) != 0)\n                    c += d;\n                d *= 0.5;\n            }\n            bit = 2147483648U;\n        }\n        return (Math.Log(c) + 0.69314718055994530941723212145818 * bitLength) \/ Math.Log(baseValue);\n    }\n    public static List&lt;FixedBigInteger> GetFactors(FixedBigInteger n)\n    {\n        var Factors = new List&lt;FixedBigInteger>();\n        var s       = n.Sqrt();\n        var a       = Three;\n        while (a &lt; s)\n        {\n            if (n % a == 0)\n            {\n                Factors.Add(a);\n                if (a * a != n)\n                    Factors.Add(n \/ a);\n            }\n            a += 2;\n        }\n        return Factors;\n    }\n    public static FixedBigInteger GreatestCommonDivisor(FixedBigInteger a, FixedBigInteger b)\n    {\n        while (b > 0)\n        {\n            var r = a % b;\n            a = b;\n            b = r;\n        }\n        return a;\n    }\n    public static FixedBigInteger LeastCommonMultiple(FixedBigInteger a, FixedBigInteger b)\n    {\n        return a * b \/ a.Gcd(b);\n    }\n    public static double Log10(FixedBigInteger value)\n    {\n        return Log(value, 10.0);\n    }\n    public static double LogN(FixedBigInteger value)\n    {\n        return Log(value, 2.0);\n    }\n    private class FixedBigIntegerConverter : TypeConverter\n    {\n        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)\n        {\n            return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);\n        }\n        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)\n        {\n            if (value != null)\n                if (TryParse($\"{value}\", out var i))\n                    return i;\n            return new FixedBigInteger(0, DataBitWidth);\n        }\n        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)\n        {\n            return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);\n        }\n        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)\n        {\n            return destinationType == typeof(string) ? $\"{value}\" : base.ConvertTo(context, culture, value, destinationType);\n        }\n    }\n}\npublic class FixedBigIntegerComparer : IComparer&lt;FixedBigInteger>\n{\n    public int Compare(FixedBigInteger left, FixedBigInteger right)\n    {\n        return left.CompareTo(right);\n    }\n    public bool Equals(FixedBigInteger left, FixedBigInteger right)\n    {\n        if (left == null || right == null)\n            return false;\n        return left.Equals(right);\n    }\n    public int GetHashCode(FixedBigInteger obj)\n    {\n        return obj.GetHashCode();\n    }\n}<\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Adjustable Fixed Bit Width Signed Integer 32,64,128,256,&#8230; Jun-11,2021: Obsolete Use xIntX Instead.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/31"}],"collection":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/comments?post=31"}],"version-history":[{"count":6,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/31\/revisions"}],"predecessor-version":[{"id":446,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/31\/revisions\/446"}],"wp:attachment":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/media?parent=31"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/categories?post=31"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/tags?post=31"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}