コード例 #1
0
        public static MultiPrecision <N> Pow2(MultiPrecision <N> x)
        {
            if (x.IsNaN)
            {
                return(NaN);
            }

            MultiPrecision <N> x_int = Floor(x);

            if (x_int.Exponent >= UIntUtil.UInt32Bits)
            {
                if (x.Sign == Sign.Plus)
                {
                    return(PositiveInfinity);
                }
                else
                {
                    return(Zero);
                }
            }

            Int64 exponent = x_int.mantissa.Value.Last() >> (UIntUtil.UInt32Bits - (int)x_int.Exponent - 1);

            if (x_int.Sign == Sign.Minus)
            {
                exponent = -exponent;
            }

            MultiPrecision <N> x_frac = x - x_int;

            MultiPrecision <N> v = Ln2 * x_frac;

            if (v.IsZero || v.Exponent < int.MinValue)
            {
                return(new MultiPrecision <N>(Sign.Plus, exponent, Mantissa <N> .One, round: false));
            }

            Accumulator <N> a = Accumulator <N> .One, m = new(v.mantissa, (int)v.Exponent), w = m;

            foreach (var t in Accumulator <N> .TaylorTable)
            {
                Accumulator <N> d = w * t;
                if (d.Digits < Length)
                {
                    break;
                }

                a += d;
                w  = Accumulator <N> .RightRoundShift(w *m, Mantissa <N> .Bits - 1);
            }

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

            MultiPrecision <N> y = new(Sign.Plus, exponent - sft + 1, n, round : false);

            return(y);
        }
コード例 #2
0
        public static MultiPrecision <N> Log2(MultiPrecision <N> x)
        {
            if (!(x >= Zero))
            {
                return(NaN);
            }
            if (x.IsZero)
            {
                return(NegativeInfinity);
            }
            if (x == PositiveInfinity)
            {
                return(PositiveInfinity);
            }
            if (x.mantissa == Mantissa <N> .One)
            {
                return(x.Exponent);
            }

            Accumulator <N> v = new(x.mantissa);

            int sft;

            for (sft = 0; sft < Accumulator <N> .Bits; sft++)
            {
                v *= v;

                if (v.Value[Accumulator <N> .Length - 1] > UIntUtil.UInt32Round)
                {
                    v = Accumulator <N> .RightRoundBlockShift(v, Mantissa <N> .Length);

                    break;
                }
                else
                {
                    v = Accumulator <N> .RightRoundShift(v, Mantissa <N> .Bits - 1);
                }
            }
            if (sft == Accumulator <N> .Bits)
            {
                return(x.Exponent);
            }

            UInt32[] mantissa = new UInt32[Mantissa <N> .Length];
            UInt32   m        = 1;

            for (int i = mantissa.Length - 1; i >= 0; i--)
            {
                for (int j = (i < mantissa.Length - 1) ? 0 : 1; j < UIntUtil.UInt32Bits; j++)
                {
                    v  *= v;
                    m <<= 1;

                    if (v.Value[Accumulator <N> .Length - 1] > UIntUtil.UInt32Round)
                    {
                        v = Accumulator <N> .RightRoundBlockShift(v, Mantissa <N> .Length);

                        m |= 1u;
                    }
                    else
                    {
                        v = Accumulator <N> .RightRoundShift(v, Mantissa <N> .Bits - 1);
                    }
                }

                mantissa[i] = m;
                m           = 0;
            }

            v *= v;
            bool round = v.Value[Accumulator <N> .Length - 1] > UIntUtil.UInt32Round;

            long intpart = x.Exponent;
            MultiPrecision <N> decpart = new(Sign.Plus, -(Int64)sft - 1, new Mantissa <N>(mantissa, enable_clone: false), round);

            MultiPrecision <N> y = intpart + decpart;

            return(y);
        }