0

行列式を計算するジェネリッククラスの関数があります。この関数は、任意のタイプの一部の入力に対して機能し、他の入力に対しては(タイプに基づいて)間違った答えを返します。

関数は次のとおりです。

    public T Determinant()
    {
        checked
        {
            int n = dimension;
            Matrix<T> a = new Matrix<T>(baseArray);
            int i, j, k;
            T det = (dynamic)0;
            for (i = 0; i < n - 1; i++)
            {
                for (j = i + 1; j < n; j++)
                {
                    det = (dynamic)a[j, i] / a[i, i];
                    for (k = i; k < n; k++)
                        a[j, k] = a[j, k] - (dynamic)det * a[i, k];
                }
            }
            det = (dynamic)1;
            for (i = 0; i < n; i++)
                det = (dynamic)det * a[i, i];

            return det;
        }
    }

オーバーフローが発生しているかどうかを確認するためにブロックを追加しましたcheckedが、明らかにオーバーフローは発生していません。

サンプル入力は、baseArrayがnew double[,] {{11, 11, 12, 17, 21, 29}, {16, 9, 25, 30, 29, 33}, {3, 13, 9, 24, 21, 24}, {23, 6, 29, 21, 23, 23}, {22, 19, 14, 30, 21, 24}, {22, 28, 20, 17, 25, 28}};正しい答え(-942755に非常に近い)を与える場合ですが、baseArrayが代わりnew int[,] {{11, 11, 12, 17, 21, 29}, {16, 9, 25, 30, 29, 33}, {3, 13, 9, 24, 21, 24}, {23, 6, 29, 21, 23, 23}, {22, 19, 14, 30, 21, 24}, {22, 28, 20, 17, 25, 28}};に15934050を答えとして与えます(近くさえありません)。

行列のインデクサーは、行列のi番目のj番目の要素を返すだけなので、問題にはなりません。

オーバーフローではないので、問題が何であるかについて私は困惑しています。何か案は?

再現するコード:

public class Matrix<T>
where T : IConvertible
{
    private int dimension;
    private T[][] baseArray;

    public Matrix(int dimensions, T[,] baseArray)
    {
        this.dimension = dimensions;
        this.baseArray = new T[dimension][];
        for (int i = 0; i < dimension; i++)
        {
            this.baseArray[i] = new T[dimension];
            for (int j = 0; j < dimension; j++)
            {
                this[i, j] = baseArray[i, j];
            }
        }
    }

    public T this[int a, int b]
    {
        get
        {
            return baseArray[a][b];
        }
        set
        {
            baseArray[a][b] = value;
        }
    }

    public T Determinant()
    {
        checked
        {
            int n = dimension;
            Matrix<T> a = new Matrix<T>(baseArray);
            int i, j, k;
            T det = (dynamic)0;
            for (i = 0; i < n - 1; i++)
            {
                for (j = i + 1; j < n; j++)
                {
                    det = (dynamic)a[j, i] / a[i, i];
                    for (k = i; k < n; k++)
                        a[j, k] = a[j, k] - (dynamic)det * a[i, k];
                }
            }
            det = (dynamic)1;
            for (i = 0; i < n; i++)
                det = (dynamic)det * a[i, i];

            return det;
        }
    }
}
4

1 に答える 1

8

値がint値の場合、整数演算を実行します。値がdouble値の場合、浮動小数点演算を実行します-それはそれと同じくらい簡単です。より簡単な例:

using System;

public class Test
{
    static void Main()
    {
        PrintResult(1, 2);      // Prints 0
        PrintResult(1.0, 2.0);  // Prints 0.5
    }

    static void PrintResult(dynamic x, dynamic y)
    {
        Console.WriteLine(x / y);
    }
}
于 2012-04-12T22:02:18.517 に答える