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)); } }
public static BigNum FromString(string v) { try { return(new BigNum(BIM.Parse(v))); } catch (System.ArgumentException) { throw new FormatException(); } }
//////////////////////////////////////////////////////////////////////////// // 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)); }
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)); }
/// <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... }
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)); }