Exemple #1
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 #2
0
        public static BigFloat operator +(BigFloat x, BigFloat y)
        {
            Contract.Requires(x.exponentSize == y.exponentSize);
            Contract.Requires(x.significandSize == y.significandSize);

            if (x.value != "" || y.value != "")
            {
                if (x.value == "NaN" || y.value == "NaN" || x.value == "+oo" && y.value == "-oo" || x.value == "-oo" && y.value == "+oo")
                {
                    return(new BigFloat("NaN", x.significandSize, x.exponentSize));
                }

                if (x.value != "")
                {
                    return(new BigFloat(x.value, x.significandSize, x.exponentSize));
                }

                return(new BigFloat(y.value, y.significandSize, y.exponentSize));
            }

            if (x.exponent > y.exponent)
            {
                BigFloat temp = x;
                x = y;
                y = temp;
            }

            BIM xsig = x.significand, ysig = y.significand;
            BIM xexp = x.exponent, yexp = y.exponent;

            if (yexp - xexp > x.significandSize) //One of the numbers is relatively insignificant
            {
                return(new BigFloat(y.isSignBitSet, y.significand, y.exponent, y.significandSize, y.exponentSize));
            }

            BIM hiddenBitPow = BIM.Pow(2, x.significandSize - 1);

            if (xexp > 0)
            {
                xsig += hiddenBitPow;
            }
            else
            {
                ++xexp;
            }

            if (yexp > 0)
            {
                ysig += hiddenBitPow;
            }
            else
            {
                ++yexp;
            }

            if (x.isSignBitSet)
            {
                xsig = -xsig;
            }
            if (y.isSignBitSet)
            {
                ysig = -ysig;
            }

            xsig >>= (int)(yexp - xexp); //Guaranteed to fit in a 32-bit integer

            ysig += xsig;

            bool isNeg = ysig < 0;

            ysig = BIM.Abs(ysig);

            if (ysig == 0)
            {
                return(new BigFloat(x.isSignBitSet && y.isSignBitSet, 0, 0, x.significandSize, x.exponentSize));
            }

            if (ysig >= hiddenBitPow * 2)
            {
                ysig >>= 1;
                ++yexp;
            }

            while (ysig < hiddenBitPow && yexp > 1)
            {
                ysig <<= 1;
                --yexp;
            }

            if (ysig < hiddenBitPow)
            {
                yexp = 0;
            }
            else
            {
                ysig -= hiddenBitPow;
            }

            if (yexp >= BIM.Pow(2, x.exponentSize) - 1)
            {
                return(new BigFloat(y.isSignBitSet ? "-oo" : "+oo", x.significandSize, x.exponentSize));
            }

            return(new BigFloat(isNeg, ysig, yexp, x.significandSize, x.exponentSize));
        }