public static bool TryParse(char[] inData, int offset, int len, IFormatProvider provider, out BigDecimal value, out Exception exception) { if (inData == null || inData.Length == 0) { exception = new FormatException("Cannot parse an empty string."); value = null; return(false); } var numberformatInfo = provider.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo; if (numberformatInfo == null) { numberformatInfo = NumberFormatInfo.CurrentInfo; } var decSep = numberformatInfo.NumberDecimalSeparator; if (decSep.Length > 1) { exception = new NotSupportedException("More than one decimal separator not yet supported"); value = null; return(false); } var cDecSep = decSep[0]; int begin = offset; // first index to be copied int last = offset + (len - 1); // last index to be copied if ((last >= inData.Length) || (offset < 0) || (len <= 0) || (last < 0)) { exception = new FormatException(); value = null; return(false); } var v = new BigDecimal(); try { var unscaledBuffer = new StringBuilder(len); int bufLength = 0; // To skip a possible '+' symbol if ((offset <= last) && (inData[offset] == '+')) { offset++; begin++; } int counter = 0; bool wasNonZero = false; // Accumulating all digits until a possible decimal point for (; (offset <= last) && (inData[offset] != cDecSep) && (inData[offset] != 'e') && (inData[offset] != 'E'); offset++) { if (!wasNonZero) { if (inData[offset] == '0') { counter++; } else { wasNonZero = true; } } } unscaledBuffer.Append(inData, begin, offset - begin); bufLength += offset - begin; // A decimal point was found if ((offset <= last) && (inData[offset] == cDecSep)) { offset++; // Accumulating all digits until a possible exponent begin = offset; for (; (offset <= last) && (inData[offset] != 'e') && (inData[offset] != 'E'); offset++) { if (!wasNonZero) { if (inData[offset] == '0') { counter++; } else { wasNonZero = true; } } } v.Scale = offset - begin; bufLength += v.Scale; unscaledBuffer.Append(inData, begin, v.Scale); } else { v.Scale = 0; } // An exponent was found if ((offset <= last) && ((inData[offset] == 'e') || (inData[offset] == 'E'))) { offset++; // Checking for a possible sign of scale begin = offset; if ((offset <= last) && (inData[offset] == '+')) { offset++; if ((offset <= last) && (inData[offset] != '-')) { begin++; } } // Accumulating all remaining digits string scaleString = new String(inData, begin, last + 1 - begin); // buffer for scale // Checking if the scale is defined long newScale = (long)v.Scale - Int32.Parse(scaleString, provider); // the new scale v.Scale = (int)newScale; if (newScale != v.Scale) { // math.02=Scale out of range. throw new FormatException(Messages.math02); //$NON-NLS-1$ } } // Parsing the unscaled value if (bufLength < 19) { long smallValue; if (!Int64.TryParse(unscaledBuffer.ToString(), NumberStyles.Integer, provider, out smallValue)) { value = null; exception = new FormatException(); return(false); } v.SmallValue = smallValue; v.BitLength = BigDecimal.CalcBitLength(v.SmallValue); } else { v.SetUnscaledValue(BigInteger.Parse(unscaledBuffer.ToString())); } v.Precision = unscaledBuffer.Length - counter; if (unscaledBuffer[0] == '-') { v.Precision--; } value = v; exception = null; return(true); } catch (Exception ex) { exception = ex; value = null; return(false); } }