Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检测double是否有限的最快方法是什么?_C#_.net_Il - Fatal编程技术网

C# 检测double是否有限的最快方法是什么?

C# 检测double是否有限的最快方法是什么?,c#,.net,il,C#,.net,Il,在不引发异常的情况下,检测IL中的double值是否为有限值(既不是NaN也不是正/负无穷大)的最快方法是什么 我考虑了以下方法(c#符号只是为了方便读者,在我的项目中,我使用IL来实现这一点): !双重。伊斯南(x)&!double.IsInfinity(x)-最明显,可能也是最慢的,因为涉及两个方法调用 (*((长*)&x))&0x7fffffffffffffl)double.NegativeInfinity&&value

在不引发异常的情况下,检测IL中的
double
值是否为有限值(既不是NaN也不是正/负无穷大)的最快方法是什么

我考虑了以下方法(c#符号只是为了方便读者,在我的项目中,我使用IL来实现这一点):

  • !双重。伊斯南(x)&!double.IsInfinity(x)
    -最明显,可能也是最慢的,因为涉及两个方法调用

  • (*((长*)&x))&0x7fffffffffffffl)<0x7ff0000000l

  • 或在IL中:

      ldloca x
      conv.u 
      ldind.i8 
      ldc.i8 0x7fffffffffffffff
      and 
      ldc.i8 0x7ff0000000000000
      clt 
    
    关于第二种方法,我的问题是:

  • 根据我的研究,这应该精确地确定任何给定的
    x
    是否是有限的。这是真的吗

  • 这是在IL中解决任务的最佳方法(性能方面),还是有更好(更快)的解决方案

  • 另外,我非常感谢有人建议我运行自己的基准并找出答案,而且我肯定会这样做。我只是想也许有人已经有了类似的问题并且知道答案。 P.P.S.是的,我意识到我们在这里谈论的是纳秒,是的,它们对于我的特殊情况非常重要

    微软使用:

    以及:


    除非使用
    !双重。伊斯南(x)&!double.IsInfinity(x)
    是您程序的真正瓶颈,我对此表示怀疑,我建议您使用这些函数,它们将更易于阅读和维护。

    不安全的上下文和混合NaN+Inf-Inf值:

    var isFinite = ((BitConverter.DoubleToInt64Bits(d) >> 52) & 0x7ff) != 0x7ff;
    
    说明:

    double是一个64位的值,存储为:

    • 符号的1位
    • 11位表示指数
    • 52位表示尾数
    扩展方法不安全上下文中:

    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对我来说是正确的。