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)); }
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)); }