2017-10-31 6 views
0

코드에 문제가있는 부분을 찾으려고합니다. FDCTHorizontal은 2D 배열의 모든 숫자를 변환하고 IDCTHorizontal은 그 값을 다시 변환해야합니다.2D 배열에서 더 많은 수학 연산이 발생하면 2D 배열에서 잘못된 값이 발생합니다.

메소드는 하나의 수학적 연산이 각 메소드의 동일한 요소 내에서 수행되는 경우에만 작동합니다. 두 작업이 수행 된 경우 IDCTHorizontal에서 반환 된 2D 배열은 FDCTHorizontal과 동일하지 않습니다.

인수 differences는 2 차원 배열의 행을 나타냅니다. 인수 YX은 출력 행 값을 나타냅니다.

두 방법에서 둘 이상의 수학 연산을 사용할 수없는 이유는 무엇입니까?

코드 :

public static void FDCTHorizontal(ref int[] differences, ref int[] Y) 
{ 
    for (int j = 0; j < differences.Length; j += 8) //split by 8 
    { 
     double[] X = new double[8]; 

     int indexCounter = 0; 
     for (int _ = j; _ < j + 8; _++) 
     { 
      X[indexCounter] = differences[_]; 
      indexCounter++; 
     } 

     //1. stage 
     double X0value = X[0]; 
     double X1value = X[1]; 
     double X2value = X[2]; 
     double X3value = X[3]; 
     double X4value = X[4]; 
     double X5value = X[5]; 
     double X6value = X[6]; 
     double X7value = X[7]; 

     //X[0] = X[0] + X7value; //if not commented, value when calling inverse method will not be the same 
     X[7] = -X[7] + X0value; 

     Y[j + 0] = Convert.ToInt32(X[0]); 
     Y[j + 4] = Convert.ToInt32(X[1]); 
     Y[j + 2] = Convert.ToInt32(X[2]); 
     Y[j + 6] = Convert.ToInt32(X[3]); 
     Y[j + 7] = Convert.ToInt32(X[4]); 
     Y[j + 3] = Convert.ToInt32(X[5]); 
     Y[j + 5] = Convert.ToInt32(X[6]); 
     Y[j + 1] = Convert.ToInt32(X[7]); //switched order 
    } 
} 

public static void IDCTHorizontal(ref int[] changedDifferences, ref int[] X) 
{ 
    for (int j = 0; j < changedDifferences.Length; j += 8) 
    { 
     double[] Y = new double[8]; 
     int indexCounter = 0; 
     for (int _ = j; _ < j + 8; _++) 
     { 
      Y[indexCounter] = changedDifferences[_]; 
      Y[indexCounter] = Y[indexCounter]; 
      indexCounter++; 
     } 

     double Y0value = Y[0]; 
     double Y1value = Y[1]; 
     double Y2value = Y[2]; 
     double Y3value = Y[3]; 
     double Y4value = Y[4]; 
     double Y5value = Y[5]; 
     double Y6value = Y[6]; 
     double Y7value = Y[7]; 

     //Y[0] = Y[0] - Y1value; //if not a comment, returned array does not have the right values 
     Y[1] = -Y[1] + Y0value; 

     X[j + 0] = Convert.ToInt32(Y[0]); 
     X[j + 1] = Convert.ToInt32(Y[4]); 
     X[j + 2] = Convert.ToInt32(Y[2]); 
     X[j + 3] = Convert.ToInt32(Y[6]); 
     X[j + 4] = Convert.ToInt32(Y[7]); 
     X[j + 5] = Convert.ToInt32(Y[3]); 
     X[j + 6] = Convert.ToInt32(Y[5]); 
     X[j + 7] = Convert.ToInt32(Y[1]); 
    } 
} 
+0

'IDCTHorizontal' 내부의 첫 번째 루프에서'Y [indexCounter] = Y [indexCounter];'가 생기고 냄새가납니다. – InBetween

답변

0

는 독립적으로 알고리즘의 정확성, 당신은 더 큰 문제를 가지고 : 당신이 모두 tranformations에서 은행원의 반올림을 수행하고 있습니다.

다음 변환이 있다고 가정하면 이고 반대의 경우는 g(x) = x - 1.5이라고 가정합니다. 두 변환을 적용하면 분명히 아무런 문제가 없습니다 : g(f(x)) = x + 1.5 - 1.5 = x. 우리가 반올림 추가하는 경우

그러나 동작은 변경 :

f´(x) = BankersRound(x + 1.5) 
g´(x) = BankersRound(x - 1.5) 

x = 3 
f´(3) = BankersRound(4.5) = 4 //round to the nearest even number 
g´(f(3)) = BankersRound(4 - 1.5) = BankersRound(2.5) = 2 //round to the nearest even number 

UPDATE : 좋아, 이것은 문제가되지 않습니다 때문에 RufusL 올바르게 지적으로, 당신은 단지 그렇게 반올림 추가 및 뺄셈을 수행 이 특별한 경우에는 문제가되어서는 안됩니다. 그러나 이것은 분명히 질문을 던집니다. 왜 double 배열을 사용하고 있습니까? 정수를 더하거나 빼는 경우 int 배열을 사용하십시오! (또는 중간 작업에서 잠재적 인 오버 플로우가 예상되는 경우 long).

+0

의미가 있습니다 만, 두 메소드의 입력이 정수이기 때문에 수행되는 유일한 연산은 더하기와 빼기이므로 반올림이 이러한 "전체"수에 어떤 영향을 미치는지 설명 할 수 있습니까? –

+0

@ RufusL 롤, 좋은 지적, 내가 알고리즘을 확인 했어야 했어! 나는 대답을 떠날거야, 아프지 않아. – InBetween