C# 检测double是否有限的最快方法是什么?
在不引发异常的情况下,检测IL中的C# 检测double是否有限的最快方法是什么?,c#,.net,il,C#,.net,Il,在不引发异常的情况下,检测IL中的double值是否为有限值(既不是NaN也不是正/负无穷大)的最快方法是什么 我考虑了以下方法(c#符号只是为了方便读者,在我的项目中,我使用IL来实现这一点): !双重。伊斯南(x)&!double.IsInfinity(x)-最明显,可能也是最慢的,因为涉及两个方法调用 (*((长*)&x))&0x7fffffffffffffl)double.NegativeInfinity&&value
double
值是否为有限值(既不是NaN也不是正/负无穷大)的最快方法是什么
我考虑了以下方法(c#符号只是为了方便读者,在我的项目中,我使用IL来实现这一点):
!双重。伊斯南(x)&!double.IsInfinity(x)
-最明显,可能也是最慢的,因为涉及两个方法调用(*((长*)&x))&0x7fffffffffffffl)<0x7ff0000000l
ldloca x
conv.u
ldind.i8
ldc.i8 0x7fffffffffffffff
and
ldc.i8 0x7ff0000000000000
clt
关于第二种方法,我的问题是:
x
是否是有限的。这是真的吗微软使用:
以及:除非使用
!双重。伊斯南(x)&!double.IsInfinity(x)
是您程序的真正瓶颈,我对此表示怀疑,我建议您使用这些函数,它们将更易于阅读和维护。无不安全的上下文和混合NaN,+Inf,-Inf值:
var isFinite = ((BitConverter.DoubleToInt64Bits(d) >> 52) & 0x7ff) != 0x7ff;
说明:
double是一个64位的值,存储为:
- 符号的1位
- 11位表示指数
internal static class ExtensionMethods
{
public static unsafe bool IsFinite(this double d) => (*(long*)&d & 0x7ff0000000000000) != 0x7ff0000000000000;
}
测试:
var isFinite = (BitConverter.DoubleToInt64Bits(d) & 0x7ff0000000000000) != 0x7ff0000000000000;
Console.WriteLine("NegativeInfinity is " + (double.NegativeInfinity.IsFinite() ? "finite" : "not finite"));
Console.WriteLine("PositiveInfinity is " + (double.PositiveInfinity.IsFinite() ? "finite" : "not finite"));
Console.WriteLine("NaN is " + (double.NaN.IsFinite() ? "finite" : "not finite"));
Console.WriteLine("Epsilon is " + (double.Epsilon.IsFinite() ? "finite" : "not finite"));
Console.WriteLine("MinValue is " + (double.MinValue.IsFinite() ? "finite" : "not finite"));
Console.WriteLine("MaxValue is " + (double.MaxValue.IsFinite() ? "finite" : "not finite"));
NegativeInfinity is not finite
PositiveInfinity is not finite
NaN is not finite
Epsilon is finite
MinValue is finite
MaxValue is finite
结果:
var isFinite = (BitConverter.DoubleToInt64Bits(d) & 0x7ff0000000000000) != 0x7ff0000000000000;
Console.WriteLine("NegativeInfinity is " + (double.NegativeInfinity.IsFinite() ? "finite" : "not finite"));
Console.WriteLine("PositiveInfinity is " + (double.PositiveInfinity.IsFinite() ? "finite" : "not finite"));
Console.WriteLine("NaN is " + (double.NaN.IsFinite() ? "finite" : "not finite"));
Console.WriteLine("Epsilon is " + (double.Epsilon.IsFinite() ? "finite" : "not finite"));
Console.WriteLine("MinValue is " + (double.MinValue.IsFinite() ? "finite" : "not finite"));
Console.WriteLine("MaxValue is " + (double.MaxValue.IsFinite() ? "finite" : "not finite"));
NegativeInfinity is not finite
PositiveInfinity is not finite
NaN is not finite
Epsilon is finite
MinValue is finite
MaxValue is finite
负不确定性不是有限的
正确定性不是有限的
NaN不是有限的
ε是有限的
最小值是有限的
最大值是有限的
没有不安全因素的良好替代方案是:
public static bool IsFinite(double value)
{
return (value > double.NegativeInfinity && value < double.PositiveInfinity);
}
公共静态bool是有限的(双值)
{
返回值(value>double.NegativeInfinity&&value
将(((long*)&x))&0x7fffffffffffl<0x7ff0000000000000L
放入内联
d函数中,然后高兴起来。@binkassaryman是的,他可以,但是如果OP不是唯一维护代码的人,他必须写一个非常非常好的注释……是的,的确如此。除非需要,否则只需使用给定的.NET framework方法。@Binkan Salaryman-在这种情况下,性能比代码的可读性更重要。谢谢你的回答和评论。@BinkanSalaryman C#没有内联关键字。(尽管JIT编译器认为它是更好的选择时会内联。)OP阐明了什么是有限数(既不是NaN也不是正/负无穷大)。我完全同意这个定义,所以对NaN来说false对我来说是正确的。