Beispiel #1
0
        public static MultiPrecision <N> ReadMultiPrecision <N>(this BinaryReader reader) where N : struct, IConstant
        {
            Sign sign = (Sign)reader.ReadByte();

            if (!Enum.IsDefined(typeof(Sign), sign))
            {
                throw new FormatException(nameof(sign));
            }

            UInt32 exponent = (UInt32)reader.ReadUInt32();

            UInt32[] mantissa = new UInt32[MultiPrecision <N> .Length];
            for (int i = 0; i < MultiPrecision <N> .Length; i++)
            {
                mantissa[i] = reader.ReadUInt32();
            }

            if (UIntUtil.IsZero(mantissa))
            {
                if (exponent != MultiPrecision <N> .ExponentMin && exponent != MultiPrecision <N> .ExponentMax)
                {
                    throw new FormatException(nameof(exponent));
                }
            }
            else
            {
                if (UIntUtil.LeadingZeroCount(mantissa) != 0u)
                {
                    throw new FormatException(nameof(mantissa));
                }
            }

            return(new MultiPrecision <N>(sign, exponent, new Mantissa <N>(mantissa, enable_clone: false)));
        }
        public static MultiPrecision <N> Truncate(MultiPrecision <N> x)
        {
            if (!x.IsFinite)
            {
                return(NaN);
            }

            if (x.Exponent >= Mantissa <N> .Bits)
            {
                throw new ArgumentException(
                          "The Truncate function was given an input value with no decimal precision.",
                          nameof(x)
                          );
            }
            if (x.Exponent < 0)
            {
                return(Zero);
            }

            UInt32[] vs = x.mantissa.Value.ToArray();

            UIntUtil.FlushLSB(vs, (int)x.Exponent);
            MultiPrecision <N> y = new(x.Sign, x.exponent, new Mantissa <N>(vs, enable_clone: false));

            return(y);
        }
        public static MultiPrecision <N> Add(MultiPrecision <N> a, long b)
        {
            if (b == 0)
            {
                return(a);
            }

            if (a.IsNaN)
            {
                return(NaN);
            }
            if (a.IsZero)
            {
                return(b);
            }
            if (!a.IsFinite)
            {
                return(a);
            }

            UInt64 b_abs = UIntUtil.Abs(b);

            if (a.Sign == UIntUtil.Sign(b))
            {
                (Mantissa <N> n, Int64 exponent, bool round) = Add(a.mantissa, b_abs, -a.Exponent);

                return(new MultiPrecision <N>(a.Sign, exponent + a.Exponent, n, round));
            }
            else
            {
                (Mantissa <N> n, Int64 exponent, bool round, Sign sign) = Diff(a.mantissa, b_abs, -a.Exponent);

                return(new MultiPrecision <N>(sign == Sign.Plus ? a.Sign : UIntUtil.Sign(b), exponent + a.Exponent, n, round));
            }
        }
Beispiel #4
0
        public static MultiPrecision <N> Random(Random random)
        {
            Accumulator <N> acc = new(new Mantissa <N>(UIntUtil.Random(random, Length, Bits), enable_clone: false));

            (Mantissa <N> n, int sft) = acc.Mantissa;

            return(new MultiPrecision <N>(Sign.Plus, Mantissa <N> .Bits - sft - 1, n, round: false));
        }
        public static MultiPrecision <N> Div(MultiPrecision <N> a, long b)
        {
            if (a.IsNaN)
            {
                return(NaN);
            }
            if (a.IsZero)
            {
                if (b == 0)
                {
                    return(NaN);
                }
                return((a.Sign == UIntUtil.Sign(b)) ? Zero : MinusZero);
            }
            if (!a.IsFinite)
            {
                return((a.Sign == UIntUtil.Sign(b)) ? PositiveInfinity : NegativeInfinity);
            }

            if (b == 0)
            {
                return((a.Sign == Sign.Plus) ? PositiveInfinity : NegativeInfinity);
            }
            if (b == 1)
            {
                return(a);
            }
            if (b == -1)
            {
                return(Neg(a));
            }

            UInt64 b_abs = UIntUtil.Abs(b);

            if (UIntUtil.IsPower2(b_abs))
            {
                MultiPrecision <N> a_power2 = Ldexp(a, -UIntUtil.Power2(b_abs));

                return(b >= 0 ? a_power2 : Neg(a_power2));
            }

            int expands = BigUInt <Plus4 <N> > .Length - BigUInt <N> .Length;

            BigUInt <Plus4 <N> > acc = new(a.mantissa.Value.ToArray(), expands);

            acc /= b_abs;

            int lzc = acc.LeadingZeroCount;

            acc <<= lzc;

            Int64        exponent = a.Exponent - lzc;
            Sign         sign     = (a.Sign == UIntUtil.Sign(b)) ? Sign.Plus : Sign.Minus;
            bool         round    = acc[expands - 1] > UIntUtil.UInt32Round;
            Mantissa <N> mantissa = new(acc.Value.Skip(expands).ToArray(), enable_clone : false);

            return(new MultiPrecision <N>(sign, exponent, mantissa, round));
        }
        public static BigUInt <N> RightRoundShift(BigUInt <N> n, int sft)
        {
            BigUInt <N> ret = n.Copy();

            ret.RightShift(sft);

            if (sft >= 1 && sft <= Bits && UIntUtil.GetLSB(n.value, sft - 1) != 0)
            {
                ret.CarryAdd(0, 1);
            }

            return(ret);
        }
Beispiel #7
0
        public override string ToString()
        {
            int bin_digits = (int)Digits, dec_digits = 0;

            // dec_digits <= bin_digits * digits(2^32 - 1) / digits(10^9 - 1) + 2
            UInt32[] dec = new UInt32[checked (bin_digits * 10 / 9 + 2)];

            for (int j = bin_digits - 1; j >= 0; j--)
            {
                UInt32 carry = value[j];

                for (int i = 0; i < dec_digits; i++)
                {
                    UInt64 res = UIntUtil.Pack(dec[i], carry);

                    (carry, dec[i]) = UIntUtil.DecimalUnpack(res);
 public static int MatchBits(BigUInt <N> a, BigUInt <N> b)
 {
     return(UIntUtil.MatchBits(Length, a.value, b.value));
 }
 public static bool operator ==(BigUInt <N> a, BigUInt <N> b)
 {
     return(UIntUtil.Equal(Length, a.value, b.value));
 }
 public static bool operator >=(BigUInt <N> a, BigUInt <N> b)
 {
     return(UIntUtil.GreaterThanOrEqual(Length, a.value, b.value));
 }
Beispiel #11
0
 public BigUInt(UInt64 v) : this()
 {
     (this.value[1], this.value[0]) = UIntUtil.Unpack(v);
 }
 /// <summary>Shift uint32 array v &gt;&gt;= sft</summary>
 private unsafe void RightShift(int sft)
 {
     UIntUtil.RightShift(value, sft);
 }
 /// <summary>Shift uint32 array v &lt;&lt;= sft</summary>
 private unsafe void LeftShift(int sft)
 {
     UIntUtil.LeftShift(value, sft);
 }
 /// <summary>Shift uint32 array v &gt;&gt;= sft * UInt32Bits</summary>
 private void RightBlockShift(int sft)
 {
     UIntUtil.RightBlockShift(value, sft);
 }