为什么Double.TryParse()对包含double.MaxValue或double.MinValue的字符串返回false?

Don*_*Don 15 c#

我有静态方法,它接受一个输入字符串,如果字符串代表一个数字,则返回原始输入字符串.如果字符串不表示数字,则处理输入字符串并返回转换后的字符串.我正在编写测试用例.我试图验证含有两种输入字符串double.MinValuedouble.MaxValue原封不动地返回.我已经阅读了很多论坛,包括StackOverflow,并提出了以下逻辑:

string doubleMax = double.MaxValue.ToString();
double d;
CultureInfo cultureInfo = new CultureInfo("en-US", true);
if (Double.TryParse(doubleMax, NumberStyles.Any, cultureInfo.NumberFormat, out d))
{
    Console.WriteLine("parsed");
}
else
{
    Console.WriteLine("couldn't parse");
}
Run Code Online (Sandbox Code Playgroud)

问题是Double.TryParse()总是返回false.我TryParse()用了很多不同的方式打电话,结果总是一样的,假的.

这个逻辑工作,如果我使用decimal.MinValue(),int.MinValue()float.MinValue().

有人能告诉我为什么我的逻辑不起作用double.MinValue吗?

Guf*_*ffa 20

这是因为浮点数的存储和显示方式.当它变成一个人类可读的字符串时,该值是四舍五入的,并且double.MaxValue它恰好被四舍五入以便它不再适合一个double.

您可以使用往返格式"R"将值转换为始终可以解析回相同值的字符串,因为它会添加额外的精度,直到返回正确的值.此外,在将数字格式化为解析时使用相同的文化,以避免文化差异:

CultureInfo cultureInfo = new CultureInfo("en-US", true);
string doubleMax = Double.MaxValue.ToString("R", cultureInfo);
Console.WriteLine(doubleMax);
double d;
if (Double.TryParse(doubleMax, NumberStyles.Any, cultureInfo.NumberFormat, out d)) {
  if (d == Double.MaxValue) {
    Console.WriteLine("parsed");
  } else {
    Console.WriteLine("value changed");
  }
} else {
  Console.WriteLine("couldn't parse");
}
Run Code Online (Sandbox Code Playgroud)

输出:

1.7976931348623157E+308
parsed
Run Code Online (Sandbox Code Playgroud)

编辑:

我添加了字符串的输出,并验证解析的值实际上仍然是MaxValue.


Jar*_*Par 7

你的逻辑没有任何问题,它只是Double.TryParseAPI的一个限制.从文档中

通常,如果传递Double.TryParse方法是通过调用Double.ToString方法创建的字符串,则返回原始Double值.但是,由于精度损失,值可能不相等.此外,尝试解析MinValue或MaxValue的字符串表示会引发OverflowException,如以下示例所示.

文档似乎是从所拍摄的Parse方法和适用于TryParse由于TryParse不抛出.但pargraph下面的示例代码使用TryParse,并希望它失败MaxValueMinValue