2012-04-12 2 views
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}};하는 경우는, 답변으로 15,934,050 제공 (근처에도 없습니다).

행렬의 인덱서는 행렬의 i 번째 j 번째 요소를 반환하므로 문제가되지 않습니다.

오버플로가 아니기 때문에 문제가 무엇인지에 대해 당황스러워합니다. 어떤 아이디어?

코드 재현 : 값이 값은 int 때, 정수 연산을 수행

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; 
     } 
    } 
} 
+1

Jon은 물론 정확합니다. 정수를 정수로 나누고 복식으로 두 배로 할 때 분명히 다른 결과를 얻습니다. 내가 이해할 수없는 것은 왜 * 처음에이 알고리즘에 어떤 부분이 있는가 *? 행렬식은 더하기, 곱하기 및 빼기 만 사용하여 계산할 수 있습니다. –

+0

@EricLippert, example에 대한 링크? – soandos

답변

8

. 값이 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); 
    } 
} 
+0

아깝고 완전히 잊어 버렸습니다. – soandos

관련 문제