调试时,Floor和Truncate不同

时间:2014-11-26 11:35:34

标签: c# .net floating-point mathdotnet

我使用Math.Net计算大型项目的基本矩阵的确定性。作为我的单元测试的一部分,我遇到了在调试测试时将float转换为int的问题。似乎附加调试器会在没有它的情况下生成不同的结果。

using System;
using MathNet.Numerics.LinearAlgebra;

public class Test
{
    public static void Main(string[] args)
    {
        Matrix<float> a = Matrix<float>.Build.Dense(2, 2, new float[] { 10, 19, 25, 10 });

        Console.WriteLine("Det {0}", a.Determinant());
        Console.WriteLine("Det Int {0}", (int)a.Determinant());
        Console.WriteLine("Det Trunc {0}", Math.Truncate(a.Determinant()));
        Console.WriteLine("Det Floor {0}", Math.Floor(a.Determinant()));
    }
}

正常运行测试时,我得到以下结果:

Det -375
Det Int -374
Det Trunc -374
Det Floor -375

但是在调试代码时我得到了这个:

Det -375
Det Int **-375**
Det Trunc **-375**
Det Floor **-376**

我已阅读this question,但似乎无法解决我的问题。在发布模式而不是调试模式下运行对结果没有影响,它似乎只与附加调试器有关。

发生了什么,我怎样才能减少出现此错误的可能性?

修改 使用Matrix<double>而不是Matrix<float>会产生正确的答案。我猜测存在某种精确错误,但我不明白为什么

1 个答案:

答案 0 :(得分:0)

用于计算决定因素的算法通常在数值上不稳定,这就是为什么在可能的情况下最好避免它们(特别是,LAPACK不提供计算决定因素的任何例程)。

我的猜测是Determinant函数正在调用LU分解例程,并且该调试模式重新排序了一系列计算,导致轻微的扰动将其推到整数边界上。