我在泛型类中有一个函数,用于计算矩阵的行列式。该函数适用于某些类型的输入,而对于其他类型的输入则会给出错误的答案(根据类型)。基于所用算术类型的不同答案(不发生溢出)
下面是函数:
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;
}
}
}
乔恩当然是正确的。很明显,当你用整数和双打来划分整数时你会得到不同的结果。我不明白的是*为什么这个算法在第一个地方有任何分歧*?行列式可以仅使用加法,乘法和减法来计算。 – 2012-04-12 22:38:33
@EricLippert,链接到示例? – soandos 2012-04-15 01:01:18