簡體   English   中英

在2D數組上進行的多項數學運算會導致2D數組內的值不正確

[英]More then one mathematical operation on 2D array causes incorrect values inside 2D array

我正在嘗試在代碼中查找麻煩的原因。 FDCTHorizontal轉換2D數組內的所有數字, IDCTHorizontal應將其轉換回去。

僅當對每種方法中的一個相同元素進行一次數學運算時,方法才有效。 如果進行了兩次操作,則從IDCTHorizontal返回的2D數組與輸入FDCTHorizontal二維數組FDCTHorizontal

參數differences表示二維數組中的一行。 參數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]);
    }
}

與算法的正確性無關,您有一個更大的問題:您正在兩次轉換中都進行銀行家的四舍五入。 您不能期望這兩種操作都是可逆的,因為舍入通常不是:

假設以下變換: 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精度數組? 如果要添加和減去整數,請使用整數數組! (如果您期望在中間操作中發生潛在的溢出,則為long)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM