예제 #1
0
        public float GetSingleValue(RoundingMode m)
        {
            if (this.IsZero)
            {
                return(0.0f);
            }
            Tuple <BigRational, int> normalized = Normalize(this);
            BigRational frac = normalized.Item1;
            int         expt = normalized.Item2;

            expt += 127;
            int loops = 24;

            while (expt < 0 && loops > 0)
            {
                frac  /= BigRational.Two;
                expt  += 1;
                loops -= 1;
            }

            if (expt <= 0)
            {
                expt = 0; frac /= BigRational.Two;
            }

            if (expt > 254)
            {
                return((frac < BigRational.Zero) ? float.NegativeInfinity : float.PositiveInfinity);
            }

            int bits = GetInt32Value_Saturate((frac * singleFractionScale).RoundingOp(m));

            if (bits < 0)
            {
                bits = (-bits) | unchecked ((int)0x80000000L);
            }
            bits &= unchecked ((int)0x807FFFFFL);
            bits |= expt << 23;

            return(BitConverter.ToSingle(BitConverter.GetBytes(bits), 0));
        }
예제 #2
0
        public double GetDoubleValue(RoundingMode m)
        {
            if (this.IsZero)
            {
                return(0.0);
            }
            Tuple <BigRational, int> normalized = Normalize(this);
            BigRational frac = normalized.Item1;
            int         expt = normalized.Item2;

            expt += 1023;
            int loops = 53;

            while (expt < 0 && loops > 0)
            {
                frac  /= BigRational.Two;
                expt  += 1;
                loops -= 1;
            }

            if (expt <= 0)
            {
                expt = 0; frac /= BigRational.Two;
            }

            if (expt > 2046)
            {
                return((frac < BigRational.Zero) ? double.NegativeInfinity : double.PositiveInfinity);
            }

            long bits = GetInt64Value_Saturate((frac * doubleFractionScale).RoundingOp(m));

            if (bits < 0)
            {
                bits = (-bits) | unchecked ((long)0x8000000000000000L);
            }
            bits &= unchecked ((long)0x800FFFFFFFFFFFFFL);
            bits |= (long)expt << 52;

            return(BitConverter.Int64BitsToDouble(bits));
        }
예제 #3
0
        public BigInteger Round()
        {
            System.Diagnostics.Debug.Assert(denominator > BigInteger.Zero);
            BigRational r = this + new BigRational(BigInteger.One, (BigInteger)2);

            if (r.Denominator == BigInteger.One)
            {
                if (!r.Numerator.IsEven)
                {
                    return(r.Numerator - BigInteger.One);
                }
                else
                {
                    return(r.Numerator);
                }
            }
            else
            {
                return(r.Floor());
            }
        }
예제 #4
0
 public RationalDatum(BigRational value)
 {
     this.value = value;
 }
예제 #5
0
        public static Tuple <BigRational, int> Normalize(BigRational r)
        {
            if (r.IsNegative)
            {
                Tuple <BigRational, int> result = Normalize(-r);
                return(new Tuple <BigRational, int>(-result.Item1, result.Item2));
            }

            Stack <BigRational> powers    = new Stack <BigRational>();
            Stack <int>         exponents = new Stack <int>();

            BigRational currentPower    = null;
            int         currentExponent = 0;

            int finalExponent = 0;

            if (r < BigRational.One)
            {
                currentPower    = BigRational.OneHalf;
                currentExponent = -1;

                while (r < currentPower)
                {
                    powers.Push(currentPower);
                    exponents.Push(currentExponent);
                    currentPower    *= currentPower;
                    currentExponent *= 2;
                }

                while (powers.Count > 0)
                {
                    currentPower    = powers.Pop();
                    currentExponent = exponents.Pop();
                    if (r < currentPower)
                    {
                        r             /= currentPower;
                        finalExponent += currentExponent;
                    }
                }
            }
            else
            {
                currentPower    = BigRational.Two;
                currentExponent = 1;

                while (r > currentPower)
                {
                    powers.Push(currentPower);
                    exponents.Push(currentExponent);
                    currentPower    *= currentPower;
                    currentExponent *= 2;
                }

                while (powers.Count > 0)
                {
                    currentPower    = powers.Pop();
                    currentExponent = exponents.Pop();
                    if (r > currentPower)
                    {
                        r             /= currentPower;
                        finalExponent += currentExponent;
                    }
                }
            }

            while (r >= BigRational.Two)
            {
                r             /= BigRational.Two;
                finalExponent += 1;
            }

            while (r < BigRational.One)
            {
                r             *= BigRational.Two;
                finalExponent -= 1;
            }

            return(new Tuple <BigRational, int>(r, finalExponent));
        }
예제 #6
0
 public static BigRational Max(BigRational a, BigRational b)
 {
     return((a > b) ? a : b);
 }
예제 #7
0
 public static BigRational Min(BigRational a, BigRational b)
 {
     return((a < b) ? a : b);
 }