如果没有OverflowException,将“1.79769313486232E + 308”转换为double?

我有这个字符串“1.79769313486232E + 308”,我试图将其转换为.NET数值(双?)但我得到以下exception。 我正在使用Convert.ToDouble() 。 这种转换的正确方法是什么?

OverflowException:对于Double,值太大或太小

问题可能是由于Double.MaxValue被转换为字符串这一事实,并且当输出字符串时,并非所有数字都被输出,而是被舍入。 解析这个值会溢出双倍。

使用Double.TryParse并随后在失败的情况下检查字符串“1.79769313486232E + 308”上的相等性并且替换Double.MaxValue应该是一个快速的解决方法,如果您需要保持字符串的方式。

编辑:当然,如果你不需要保持字符串的方式,使用Round Trip格式说明符首先产生字符串,正如Jon在他的回答中所描述的那样 。

不幸的是,这个值大于double.MaxValue ,因此是例外。

正如codekaizen建议的那样,您可以对字符串进行硬编码测试。 如果您是首先生成字符串的人,那么更好的(IMO)替代方法是使用“r”格式说明符。 然后你生成的字符串将是“1.7976931348623157E + 308”,然后正确解析:

 string s = double.MaxValue.ToString("r"); double d = double.Parse(s); // No exception 

显然,如果您无法控制数据,那将无济于事 – 但是您应该了解在这种情况下您可能会丢失数据。

您可以尝试使用double.Parse()double.TryParse()而不是Convert.ToDouble() ,但我不确定您会得到更好的结果。 顺便提一下,你提供的字符串等于double.MaxValue ,它(当然)是double中可以包含的最大值,因此很可能是你的错误发生的地方。 浮点数字类型很挑剔,所以我假设正在进行某种舍入并将其推出类型的边界之外。

您也可以尝试decimal数据类型。 你可能会有更好的运气。

这就是我想出的。 感谢Jon Skeet和codekaizen。

 private double convertToDouble(string str) { double dbl; if (double.TryParse(str, out dbl)) return dbl; if (str == "1.79769313486232E+308") return double.MaxValue; return double.MinValue; } 

演示问题和解决方案:

 var s = double.MaxValue.ToString(); double d; if (!double.TryParse(s, out d)) { d = s.Equals(double.MaxValue) ? double.MaxValue : double.MinValue; } 

这是一个更通用的实现,它表示不同的格式和文化,并且更宽容:

 #region MatchDoubleMinMaxValuesRegex ///  /// This regex matches strings which represents either a  or a . /// If it is a  then the group "isNegative" will be matched as . ///  private static readonly Regex MatchDoubleMinMaxValuesRegex = new Regex( @" ^ (?>(?-)|\+?) 1 (?>[,.]?) 79769313486232 (?> [eE]\+308| 0{294}(?>[,.]|$) ) ", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace ); #endregion ///  /// Converts the string representation of a number in a specified culture-specific format to its double-precision floating-point number equivalent. /// This implementation is more tolerant compared to the native double.Parse implementation: /// strings representing  and  can be parsed without . ///  /// A string that contains a number to convert. /// For some type conversions optional culture information that shall be used to parse the value. /// If not specified, then the Current Culture will be used. /// For some type conversions optional number style configuration that shall be used to parse the value. /// If not specified, then the default will be used. /// A double-precision floating-point number that is equivalent to the numeric value or symbol specified in . ///  is null. ///  does not represent a number in a valid format. ///  represents a number that is less than  or greater than . public static double ParseDoubleEx(string s, CultureInfo cultureInfo = null, NumberStyles? numberStyles = null) { // Try parse double tempValue; bool parseSuccess = (numberStyles != null) ? double.TryParse(s, numberStyles.Value, cultureInfo, out tempValue) : double.TryParse(s, NumberStyles.Any, cultureInfo, out tempValue); // If parsing failed, check for Min or Max Value (by pattern) if (parseSuccess == false) { Match match = MatchDoubleMinMaxValuesRegex.Match(s); if (match.Success == true) tempValue = (match.Groups["isNegative"].Success == false) ? double.MaxValue : double.MinValue; else throw new OverflowException("A double-precision floating-point number that is equivalent to the numeric value or symbol specified in s."); } return tempValue; } 

例外情况说,这个数字对于双倍来说太大了。 您将不得不找到一个大型库来为您处理,因为在.Net库中没有任何我知道的处理非常大的数字。