我试图在我的代码中找到麻烦的原因。 FDCTHorizontal
转换2D数组中的所有数字,IDCTHorizontal
应该将它们转换回来。
只有在每个方法内的一个相同元素上完成一个数学运算时,方法才能工作。如果进行了两次操作,则IDCTHorizontal
返回的2D数组与输入FDCTHorizontal
的数组不同。
参数differences
表示2D数组中的一行。参数Y
和X
表示输出行值。
为什么我不能在两种方法中使用多个数学运算?
代码:
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 :(得分:0)
除了算法的正确性之外,还有一个更大的问题:您在两次转换中执行银行家舍入。您不能指望两个操作都是可逆的,因为舍入通常不是:
假设以下转换:f(x) = x + 1.5
和相反的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
更新:好的,这不是问题,因为正如RufusL正确指出的那样,您只是执行加法和减法,因此在这种情况下舍入不应成为问题。但这显然引出了一个问题:为什么要使用double
数组开始?如果要添加和减去整数,请使用整数数组! (或者如果您期望在中间操作中出现潜在的溢出,则为多。)