Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.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/batch-file/5.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# C编译器“优化代码”:仅对代码片段禁用_C#_Compiler Optimization - Fatal编程技术网

C# C编译器“优化代码”:仅对代码片段禁用

C# C编译器“优化代码”:仅对代码片段禁用,c#,compiler-optimization,C#,Compiler Optimization,我有一个C代码,当“优化代码”选项关闭时,该代码运行良好,但在其他情况下失败。是否有任何函数或类属性可以阻止函数或类的优化,但让编译器优化其他函数或类 我尝试了不安全或MethodImpl,但没有成功 谢谢 编辑: 我又做了一些测试。。。 代码如下所示: double arg = (Math.PI / 2d - Math.Atan2(a, d)); 当a=1且d=0时,arg应为0。 该代码是Excel通过ExcelDNA调用的函数 从优化的控制台应用程序调用相同的代码:确定 从Excel调

我有一个C代码,当“优化代码”选项关闭时,该代码运行良好,但在其他情况下失败。是否有任何函数或类属性可以阻止函数或类的优化,但让编译器优化其他函数或类

我尝试了不安全或MethodImpl,但没有成功

谢谢

编辑: 我又做了一些测试。。。 代码如下所示:

double arg = (Math.PI / 2d - Math.Atan2(a, d)); 
当a=1且d=0时,arg应为0。 该代码是Excel通过ExcelDNA调用的函数

从优化的控制台应用程序调用相同的代码:确定

从Excel调用此代码而不进行优化:确定

通过优化从Excel调用此代码:Not OK,arg==0为false,而arg是一个非常小的接近0的值,但不是0


调用函数之前的[MethodImplOptions.NoOptimization]的结果相同。

这是处理浮点数据类型时得到的结果。你不能得到精确的0,但是一个非常接近的值,因为一个双精度的精度是有限的,并且不是每个值都能被表示出来,有时这些微小的精度误差加起来。您需要检查该值是否足够接近0

这就是处理浮点数据类型时得到的结果。你不能得到精确的0,但是一个非常接近的值,因为一个双精度的精度是有限的,并且不是每个值都能被表示出来,有时这些微小的精度误差加起来。您需要检查该值是否足够接近0

这很可能和Excel可能已经设置的有关-这意味着您的程序正在计算的浮点值略有不同,因为程序Excel托管您的程序集DLL。这可能会影响计算结果的方式,或自动强制为零的方式/值

为了确保您不会遇到不同浮点模式和/或错误的问题,您应该检查是否相等,而不是检查值是否非常接近

我还移植了重新解释整数比较,以防您发现它更适合处理更大的值

public class AlmostDoubleComparer : IComparer<double>
{
    public static readonly AlmostDoubleComparer Default = new AlmostDoubleComparer();
    public const double MaxUnitsInTheLastPlace = 3;

    public static bool IsZero(double x)
    {
        return Compare(x, 0) == 0;
    }

    public static int Compare(double x, double y)
    {
        // Very important that cmp(x, y) == cmp(y, x)
        if (Double.IsNaN(x) || Double.IsNaN(y))
            return 1;
        if (Double.IsInfinity(x) || Double.IsInfinity(y))
            return 1;

        var ix = DoubleInt64.Reinterpret(x);
        var iy = DoubleInt64.Reinterpret(y);
        var diff = Math.Abs(ix - iy);
        if (diff < MaxUnitsInTheLastPlace)
            return 0;

        if (ix < iy)
            return -1;
        else
            return 1;
    }

    int IComparer<double>.Compare(double x, double y)
    {
        return Compare(x, y);
    }
}

[StructLayout(LayoutKind.Explicit)]
public struct DoubleInt64
{
    [FieldOffset(0)]
    private double _double;
    [FieldOffset(0)]
    private long _int64;

    private DoubleInt64(long value)
    {
        _double = 0d;
        _int64 = value;
    }

    private DoubleInt64(double value)
    {
        _int64 = 0;
        _double = value;
    }

    public static double Reinterpret(long value)
    {
        return new DoubleInt64(value)._double;
    }

    public static long Reinterpret(double value)
    {
        return new DoubleInt64(value)._int64;
    }
}

或者,您可以尝试和程序集进行比较,看看是否可以解决Excel的模式或它如何承载CLR的问题。

这很可能与Excel可能已设置的模式有关-这意味着您的程序正在计算浮点值,这与Excel承载程序集DLL的程序略有不同。这可能会影响计算结果的方式,或自动强制为零的方式/值

为了确保您不会遇到不同浮点模式和/或错误的问题,您应该检查是否相等,而不是检查值是否非常接近

我还移植了重新解释整数比较,以防您发现它更适合处理更大的值

public class AlmostDoubleComparer : IComparer<double>
{
    public static readonly AlmostDoubleComparer Default = new AlmostDoubleComparer();
    public const double MaxUnitsInTheLastPlace = 3;

    public static bool IsZero(double x)
    {
        return Compare(x, 0) == 0;
    }

    public static int Compare(double x, double y)
    {
        // Very important that cmp(x, y) == cmp(y, x)
        if (Double.IsNaN(x) || Double.IsNaN(y))
            return 1;
        if (Double.IsInfinity(x) || Double.IsInfinity(y))
            return 1;

        var ix = DoubleInt64.Reinterpret(x);
        var iy = DoubleInt64.Reinterpret(y);
        var diff = Math.Abs(ix - iy);
        if (diff < MaxUnitsInTheLastPlace)
            return 0;

        if (ix < iy)
            return -1;
        else
            return 1;
    }

    int IComparer<double>.Compare(double x, double y)
    {
        return Compare(x, y);
    }
}

[StructLayout(LayoutKind.Explicit)]
public struct DoubleInt64
{
    [FieldOffset(0)]
    private double _double;
    [FieldOffset(0)]
    private long _int64;

    private DoubleInt64(long value)
    {
        _double = 0d;
        _int64 = value;
    }

    private DoubleInt64(double value)
    {
        _int64 = 0;
        _double = value;
    }

    public static double Reinterpret(long value)
    {
        return new DoubleInt64(value)._double;
    }

    public static long Reinterpret(double value)
    {
        return new DoubleInt64(value)._int64;
    }
}

或者,您可以尝试对程序集进行测试,看看是否可以解决Excel的模式或它如何承载CLR的问题。

失败是什么意思?您是否遇到异常,是执行缓慢还是其他原因?优化后,代码的功能不应更改。如果在启用优化后失败,则可能是错误的。。。请把密码贴出来!如果您尝试过MethodImpl.NoOptimization,但仍然失败,我怀疑您的问题是优化,我怀疑它会是什么,这是另外一回事。发布一些代码。尝试使用十进制而不是双精度。我认为使用十进制不是一个好主意,Excel传递的参数是双精度的,atan2传递的参数也是一样的。失败是什么意思?您是否遇到异常,是执行缓慢还是其他原因?优化后,代码的功能不应更改。如果在启用优化后失败,则可能是错误的。。。请把密码贴出来!如果您尝试过MethodImpl.NoOptimization,但仍然失败,我怀疑您的问题是优化,我怀疑它会是什么,这是另外一回事。发布一些代码。尝试使用十进制而不是双精度。我认为使用十进制不是一个好主意,Excel传递的参数是双精度的,atan2的参数也是一样。我认为将十进制或int与Math.atan2一起使用没有意义。使用十进制并不会神奇地给你们无限精度,它只是让你们精确地表示小数点。我什么时候说过十进制会提供无限精度的?这也取决于他想用它做什么。结果是一个非常小的值,你不能对不精确性做任何改变。将双精度值与常量值(如0)进行比较通常会导致此类错误。是的,使用双精度值会导致此类错误。但使用十进制有什么帮助呢?它可以最大限度地减少舍入误差,但你是对的,在这种情况下可能没有帮助。你不能得到精确的0,但得到非常接近的值
e=>ok,但为什么在optim打开的情况下从Excel调用时,arg==0为false,而在optim关闭的情况下,arg==0对于相同的参数为true?我认为将decimal或int与Math.Atan2一起使用没有意义。使用十进制并不会神奇地给你们无限精度,它只是让你们精确地表示小数点。我什么时候说过十进制会提供无限精度的?这也取决于他想用它做什么。结果是一个非常小的值,你不能对不精确性做任何改变。将双精度值与常量值(如0)进行比较通常会导致此类错误。是的,使用双精度值会导致此类错误。但是使用十进制有什么帮助呢?它可以最大限度地减少舍入误差,但是你是对的,在这种情况下可能没有帮助。你没有得到精确的0,但是一个非常接近的值=>ok,但是为什么在启用optim的情况下从Excel调用时,arg==0为false,而在禁用optim时,对于相同的参数,arg==0为真?这很可能与Excel设置的浮点模式有关=>感谢链接,我会检查的。@Poca请记住,如果您将其更改回您期望的值,我不确定默认值是什么,您可能会弄乱Excel-因此最好进行“接近度”检查。这很可能与Excel设置的浮点模式有关=>感谢链接,我会检查的。@Poca请记住,如果您将其更改回您期望的值,我不确定默认值是什么,您可能会弄乱Excel-因此最好进行“接近度”检查。