为什么 C# TryParse 不处理 NaN?
Why does C# TryParse not handle NaN?
我有一些常用的方法来在读取一些旧的 Fortran 数据时使用默认值覆盖进行解析。偶尔数据有 NaN (Not a number)
应该是数值的地方。我预计 TryParse 会看到字符串 "NaN" 并且无法解析。但是,TryParse 成功解析并将 NaN
放入数值中。这是预期的行为吗?如果这是预期的,是否还有我应该寻找的其他 "gotcha" 值?
public static double GetDoubleFromString(string s, double defaultOnFailure = 0)
{
//Must be here due to TryParse returning NaN to d and result is set to true below
if (s.Contains("NaN"))
{
log.Warn(string.Format("String contained NaN, returning defaultOnFailure {0} string was {1}", defaultOnFailure, s));
return defaultOnFailure;
}
var d = defaultOnFailure;
if (!double.TryParse(s.Trim(), out d))
{
log.Warn(string.Format("Failed to parse double from string returning defaultOnFailure {0} string was {1}", defaultOnFailure, s));
}
return d;
}
更新
我觉得应该提一下,这只发生在 double、long 和 int 上,而不是 return NaN 值。请参阅下面的示例代码,Common.... 代码只是格式化 Console.WriteLine 或停止以在控制台执行。请参阅下面的屏幕截图了解输出。
public static void NanTestMain()
{
Common.WriteBlankWithTitle("Test parse NaN");
string s = "NaN";
Common.WriteBlankWithTitle("NaN to Int");
int i;
var intSuccess = int.TryParse(s, out i);
Console.WriteLine(string.Format("Int parse of {0} parse = {1}", i, intSuccess));
Common.WriteBlankWithTitle("NaN to Double");
double d;
var doubleSuccess = double.TryParse(s, out d);
Console.WriteLine(string.Format("Double parse of {0} parse = {1}", d, doubleSuccess));
Common.WriteBlankWithTitle("NaN to Long");
long l;
var longSuccess = long.TryParse(s, out l);
Console.WriteLine(string.Format("Long parse of {0} parse = {1}", l, longSuccess));
Common.Pause();
}
Double.NaN 是 double 的有效值,所以这是正常的。
还有负无穷大和正无穷大。检查 here 其他可能的 'special' 值。
来自MSDN:
The s parameter can contain NumberFormatInfo.PositiveInfinitySymbol, NumberFormatInfo.NegativeInfinitySymbol, or NumberFormatInfo.NaNSymbol for the culture indicated by provider.
需要注意三个 "special" 值。但是,最后几句话很关键——根据当前的文化,您可能会看到 "NaN"
!
以外的内容
我有一些常用的方法来在读取一些旧的 Fortran 数据时使用默认值覆盖进行解析。偶尔数据有 NaN (Not a number)
应该是数值的地方。我预计 TryParse 会看到字符串 "NaN" 并且无法解析。但是,TryParse 成功解析并将 NaN
放入数值中。这是预期的行为吗?如果这是预期的,是否还有我应该寻找的其他 "gotcha" 值?
public static double GetDoubleFromString(string s, double defaultOnFailure = 0)
{
//Must be here due to TryParse returning NaN to d and result is set to true below
if (s.Contains("NaN"))
{
log.Warn(string.Format("String contained NaN, returning defaultOnFailure {0} string was {1}", defaultOnFailure, s));
return defaultOnFailure;
}
var d = defaultOnFailure;
if (!double.TryParse(s.Trim(), out d))
{
log.Warn(string.Format("Failed to parse double from string returning defaultOnFailure {0} string was {1}", defaultOnFailure, s));
}
return d;
}
更新
我觉得应该提一下,这只发生在 double、long 和 int 上,而不是 return NaN 值。请参阅下面的示例代码,Common.... 代码只是格式化 Console.WriteLine 或停止以在控制台执行。请参阅下面的屏幕截图了解输出。
public static void NanTestMain()
{
Common.WriteBlankWithTitle("Test parse NaN");
string s = "NaN";
Common.WriteBlankWithTitle("NaN to Int");
int i;
var intSuccess = int.TryParse(s, out i);
Console.WriteLine(string.Format("Int parse of {0} parse = {1}", i, intSuccess));
Common.WriteBlankWithTitle("NaN to Double");
double d;
var doubleSuccess = double.TryParse(s, out d);
Console.WriteLine(string.Format("Double parse of {0} parse = {1}", d, doubleSuccess));
Common.WriteBlankWithTitle("NaN to Long");
long l;
var longSuccess = long.TryParse(s, out l);
Console.WriteLine(string.Format("Long parse of {0} parse = {1}", l, longSuccess));
Common.Pause();
}
Double.NaN 是 double 的有效值,所以这是正常的。 还有负无穷大和正无穷大。检查 here 其他可能的 'special' 值。
来自MSDN:
The s parameter can contain NumberFormatInfo.PositiveInfinitySymbol, NumberFormatInfo.NegativeInfinitySymbol, or NumberFormatInfo.NaNSymbol for the culture indicated by provider.
需要注意三个 "special" 值。但是,最后几句话很关键——根据当前的文化,您可能会看到 "NaN"
!