检查Double的最短方法是"NaN"
本文关键字:quot NaN 方法 Double 检查 | 更新日期: 2023-09-27 18:12:25
以Double.PositiveInfinity
为参数调用Double.IsNaN()
时,结果为false。这违背了我的直觉,因为无穷大不是一个数字。显然,"NaN"在。net中只以常量的形式存在,这是由IEEE标准描述的还是自定义的实现细节?是否有比
Double
是否为"NaN":(Double.IsNaN(d) || Double.IsPositiveInfinity(d) || Double.IsNegativeInfinity(d))
或
(Double.IsNaN(d) || Double.IsInfinity(d))
正如MSDN所说,NaN表示结果未定义。对于无穷大,结果被定义:
当操作的结果为时,方法或操作符返回NaN未定义的。例如,0除以0的结果是NaN,即下面的示例显示。(但请注意,除一个非零的数by zero返回PositiveInfinity或NegativeInfinity,具体取决于在除数的符号上)
所以,把无穷大当作NaN处理不是一个好主意。您可以编写扩展方法来检查value是否不是NaN或无穷大:
// Or IsNanOrInfinity
public static bool HasValue(this double value)
{
return !Double.IsNaN(value) && !Double.IsInfinity(value);
}
你不再需要SergeyBerezovskiy的回答。
double
有IsFinite()
方法来检查双精度是否是有限数(不是NaN
或Infinity
):
double.IsFinite(d)
查看。net Framework和。net Core的源代码
基于IEEE标准754的Double
类型中有三个特殊值。一个是正无穷,另一个是负无穷,最后一个是非数字(NaN)。Double.IsNaN
方法所做的就是检查变量中的值是否为这个特殊的NaN值。
如果您希望double
的值始终是一个数字,您可以使用这个FiniteOrDefault
扩展。当然,它的灵感来自谢尔盖·别列佐夫斯基的回答。
public static bool HasValue(this double value)
{
return !double.IsNaN(value) && !double.IsInfinity(value);
}
/// <summary>
/// Returns zero when double is NaN or Infinte
/// </summary>
public static double FiniteOrDefault(this double value)
{
return value.HasValue() ? value : default;
}
这样,像下面这样的代码就更容易读了:
Rect dimensions = new Rect
{
X = Canvas.GetLeft(Control).FiniteOrDefault(),
Y = Canvas.GetTop(Control).FiniteOrDefault(),
Width = Control.ActualWidth.FiniteOrDefault(),
Height = Control.ActualHeight.FiniteOrDefault()
};
最后,您所看到的是双精度数的位值。double使用的IEEE标准754规定:
- 正无穷设置所有指数位,所有有效位不设置,符号位不设置。
- 负无穷设置所有指数位,所有有效位不设置,和符号位设置。
- Nan设置了所有指数位和至少一个有效位。符号位可以设置也可以不设置。在c#中,常量double。NaN具有符号位和最高有效位集。
因此,如果你不想使用内置函数,你可以简单地检查是否自己设置了所有的Exponent位。您可以通过以下两种方式之一来做到这一点:使用不安全的代码来提取double的长值,或者使用BitConverter.DoubleToInt64Bits
,然后检查指数位。
public unsafe static bool IsNaNorInfinity(double d)
{
return (*(long*)(&d) & 0x7FF0000000000000L) == 0x7FF0000000000000L;
}
public static bool IsNaNorInfinity(double d)
{
return (BitConverter.DoubleToInt64Bits(d) & 0x7FF0000000000000L) == 0x7FF0000000000000L;
}