Exemple #1
0
        public static BigDec FromString(string v)
        {
            if (v == null)
            {
                throw new FormatException();
            }

            BIM integral = BIM.Zero;
            BIM fraction = BIM.Zero;
            int exponent = 0;

            int len = v.Length;

            int i = v.IndexOf('e');

            if (i >= 0)
            {
                if (i + 1 == v.Length)
                {
                    throw new FormatException();
                }
                exponent = Int32.Parse(v.Substring(i + 1, len - i - 1));
                len      = i;
            }

            int fractionLen = 0;

            i = v.IndexOf('.');
            if (i >= 0)
            {
                if (i + 1 == v.Length)
                {
                    throw new FormatException();
                }
                fractionLen = len - i - 1;
                fraction    = BIM.Parse(v.Substring(i + 1, fractionLen));
                len         = i;
            }

            integral = BIM.Parse(v.Substring(0, len));

            if (!fraction.IsZero)
            {
                while (fractionLen > 0)
                {
                    integral    = integral * ten;
                    exponent    = exponent - 1;
                    fractionLen = fractionLen - 1;
                }
            }

            if (integral.Sign == -1)
            {
                return(new BigDec(integral - fraction, exponent));
            }
            else
            {
                return(new BigDec(integral + fraction, exponent));
            }
        }
Exemple #2
0
 public static BigNum FromString(string v)
 {
     try {
         return(new BigNum(BIM.Parse(v)));
     } catch (System.ArgumentException) {
         throw new FormatException();
     }
 }
Exemple #3
0
        ////////////////////////////////////////////////////////////////////////////
        // Conversion operations

        /// <summary>
        /// NOTE: THIS METHOD MAY NOT WORK AS EXPECTED!!!
        /// Converts the given decimal value (provided as a string) to the nearest floating point approximation
        /// the returned fp assumes the given significand and exponent size
        /// </summary>
        /// <param name="value"></param>
        /// <param name="significandSize"></param>
        /// <param name="exponentSize"></param>
        /// <returns></returns>
        public static BigFloat Round(String value, int exponentSize, int significandSize)
        {
            int i = value.IndexOf('.');

            if (i == -1)
            {
                return(Round(BIM.Parse(value), BIM.Zero, exponentSize, significandSize));
            }
            return(Round(i == 0 ? BIM.Zero : BIM.Parse(value.Substring(0, i)), BIM.Parse(value.Substring(i + 1, value.Length - i - 1)), exponentSize, significandSize));
        }
Exemple #4
0
        public static BigFloat FromString(String s)
        {
            /*
             * String must be either of the format *e*f*e*
             * or of the special value formats: 0NaN*e* 0nan*e* 0+oo*e* 0-oo*e*
             * Where * indicates an integer value (digit)
             */
            BIM  sig, exp;
            int  sigSize, expSize;
            bool isNeg;

            if (s.IndexOf('f') == -1)
            {
                String val = s;
                sigSize = int.Parse(s.Substring(4, s.IndexOf('e') - 4));
                expSize = int.Parse(s.Substring(s.IndexOf('e') + 1));
                if (sigSize <= 0 || expSize <= 0)
                {
                    throw new FormatException("Significand and Exponent sizes must be greater than 0");
                }
                return(new BigFloat(val, sigSize, expSize));
            }

            sig     = BIM.Parse(s.Substring(0, s.IndexOf('e')));
            exp     = BIM.Parse(s.Substring(s.IndexOf('e') + 1, s.IndexOf('f') - s.IndexOf('e') - 1));
            sigSize = int.Parse(s.Substring(s.IndexOf('f') + 1, s.IndexOf('e', s.IndexOf('e') + 1) - s.IndexOf('f') - 1));
            expSize = int.Parse(s.Substring(s.IndexOf('e', s.IndexOf('e') + 1) + 1));
            isNeg   = s[0] == '-'; //We do this so that -0 is parsed correctly

            if (sigSize <= 0 || expSize <= 0)
            {
                throw new FormatException("Significand and Exponent sizes must be greater than 0");
            }

            sigSize = sigSize - 1;  //Get rid of sign bit
            sig     = BIM.Abs(sig); //sig must be positive
            //Uncomment if you want to shift the exponent for the user (i.e. 0e-1f24e8 --> 0e126f24e8)
            //exp = exp + BIM.Pow(new BIM(2), expSize-1) - BIM.One;

            if (exp < 0 || exp >= BIM.Pow(new BIM(2), expSize))
            {
                throw new FormatException("The given exponent " + exp + " cannot fit in the bit size " + expSize);
            }

            if (sig >= BIM.Pow(new BIM(2), sigSize))
            {
                throw new FormatException("The given significand " + sig + " cannot fit in the bit size " + (sigSize + 1));
            }

            return(new BigFloat(isNeg, sig, exp, sigSize, expSize));
        }
Exemple #5
0
        /// <summary>
        /// NOTE:  THIS METHOD MAY NOT WORK AS EXPECTED!!!!
        /// Converts value.dec_value to a the closest float approximation with the given significandSize, exponentSize
        /// Returns the result of this calculation
        /// </summary>
        /// <param name="value"></param>
        /// <param name="power"></param>
        /// <param name="significandSize"></param>
        /// <param name="exponentSize"></param>
        /// <returns></returns>
        public static BigFloat Round(BIM value, BIM dec_value, int exponentSize, int significandSize)
        {
            int exp     = 0;
            BIM one     = new BIM(1);
            BIM ten     = new BIM(10);
            BIM dec_max = new BIM(0); //represents the order of magnitude of dec_value for carrying during calculations

            //First, determine the exponent
            while (value > one)            //Divide by two, increment exponent by 1
            {
                if (!(value % two).IsZero) //Add "1.0" to the decimal
                {
                    dec_max = new BIM(10);
                    while (dec_max < dec_value)
                    {
                        dec_max = dec_max * ten;
                    }
                    dec_value = dec_value + dec_max;
                }
                value = value / two;
                if (!(dec_value % ten).IsZero)
                {
                    dec_value = dec_value * ten; //Creates excess zeroes to avoid losing data during division
                }
                dec_value = dec_value / two;
                exp++;
            }
            if (value.IsZero && !dec_value.IsZero)
            {
                dec_max = new BIM(10);
                while (dec_max < dec_value)
                {
                    dec_max = dec_max * ten;
                }
                while (value.IsZero)//Multiply by two, decrement exponent by 1
                {
                    dec_value = dec_value * two;
                    if (dec_value >= dec_max)
                    {
                        dec_value = dec_value - dec_max;
                        value     = value + one;
                    }
                    exp--;
                }
            }

            //Second, calculate the significand
            value   = new BIM(0); //remove implicit bit
            dec_max = new BIM(10);
            while (dec_max < dec_value)
            {
                dec_max = dec_max * ten;
            }
            for (int i = significandSize; i > 0 && !dec_value.IsZero; i--) //Multiply by two until the significand is fully calculated
            {
                dec_value = dec_value * two;
                if (dec_value >= dec_max)
                {
                    dec_value = dec_value - dec_max;
                    value     = value + two_n(i); //Note that i is decrementing so that the most significant bit is left-most in the representation
                }
            }

            return(new BigFloat(false, BIM.Zero, BIM.Parse(value.ToString()), exponentSize, significandSize)); //Sign not actually checked...
        }
Exemple #6
0
        public static BigFloat FromString(String s)
        {
            /*
             * String must be either of the format [-]0x^.^e*f*e*
             * or of the special value formats: 0NaN*e* 0nan*e* 0+oo*e* 0-oo*e*
             * Where ^ indicates a hexadecimal value and * indicates an integer value
             */

            int posLastE = s.LastIndexOf('e');

            int expSize = int.Parse(s.Substring(posLastE + 1));

            if (expSize <= 1)
            {
                throw new FormatException("Exponent size must be greater than 1");
            }

            int posLastF = s.LastIndexOf('f');
            int posSig   = posLastF + 1;

            if (posLastF == -1)//NaN, +oo, -oo
            {
                posSig = 4;
            }

            int sigSize = int.Parse(s.Substring(posSig, posLastE - posSig));

            if (sigSize <= 1)
            {
                throw new FormatException("Significand size must be greater than 1");
            }

            if (posLastF == -1)//NaN, +oo, -oo
            {
                return(new BigFloat(s.Substring(1, 3), sigSize, expSize));
            }

            bool isNeg = s[0] == '-';

            int posX           = s.IndexOf('x');
            int posSecondLastE = s.LastIndexOf('e', posLastE - 1);

            string hexSig = s.Substring(posX + 1, posSecondLastE - (posX + 1));
            BIM    oldExp = BIM.Parse(s.Substring(posSecondLastE + 1, posLastF - (posSecondLastE + 1)));

            string binSig = string.Join(string.Empty,
                                        hexSig.Select(
                                            c => (c == '.' ? "." : Convert.ToString(Convert.ToInt32(c.ToString(), 16), 2).PadLeft(4, '0'))
                                            )
                                        );

            int posDec = binSig.IndexOf('.');

            binSig = binSig.Remove(posDec, 1);

            int posFirstOne = binSig.IndexOf('1');
            int posLastOne  = binSig.LastIndexOf('1');

            if (posFirstOne == -1)
            {
                return(new BigFloat(isNeg, 0, 0, sigSize, expSize));
            }

            binSig = binSig.Substring(posFirstOne, posLastOne - posFirstOne + 1);

            BIM bias       = two_n(expSize - 1) - 1;
            BIM upperBound = 2 * bias + 1;

            BIM newExp = 4 * oldExp + bias + (posDec - posFirstOne - 1);

            if (newExp <= 0)
            {
                if (-newExp <= (sigSize - 1) - binSig.Length)
                {
                    binSig = new string('0', (int)-newExp) + binSig;
                    newExp = 0;
                }
            }
            else
            {
                binSig = binSig.Substring(1);
            }

            if (newExp < 0 || newExp >= upperBound)
            {
                throw new FormatException("The given exponent cannot fit in the bit size " + expSize);
            }

            binSig = binSig.PadRight(sigSize - 1, '0');

            if (binSig.Length > sigSize - 1)
            {
                throw new FormatException("The given significand cannot fit in the bit size " + (sigSize - 1));
            }

            BIM newSig = 0;

            foreach (char b in binSig)
            {
                if (b != '.')
                {
                    newSig <<= 1;
                    newSig  += b - '0';
                }
            }

            return(new BigFloat(isNeg, newSig, newExp, sigSize, expSize));
        }