簡體   English   中英

確保GetHashCode()重載對於半相等的R3浮點向量返回相同的方法

[英]Method to ensure GetHashCode() overload returns the same for semi-equal R3 float vectors

這是給二進制和原始專家的。 我正在實現一個float R3向量結構,而我對“等於”的定義實際上是“幾乎相等”。 具體來說,對於比較向量的所有坐標,Abs((a [i]-b [i])/(a [i] + b [i]))<.00001返回true。

private static bool FloatEquality(float a, float b)
    {
        if (a == b)
        {
            return true;
        }
        else
        {
            float e;
            try
            {
                e = (b - a) / (b + a);
            }
            catch (DivideByZeroException)
            {
                float g = float.Epsilon;
                e = (b - a) / g;
            }
            //AppConsole.AppConsole.Instance.WriteLine(e);
            if (e < .00001f && e > -.00001f)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

我的問題是,由於我希望能夠將這些向量用作字典的“鍵”,因此確定是否有一種方法可以使散列值在滿足此要求的向量上相同。

如您所見,以上代碼用於檢查3個不同坐標上的相等性。

我正在考慮從三個浮點坐標中提取字節,並從每個中間使用中間兩個。

(以下不是代碼,但除非縮進,否則Stack Overflow不會讓我發布它)

Vector(x,y,z):
x's float byte[] = [ x1 x2 x3 x3 ]
y's float byte[] = [ y1 y2 y3 y4 ]
z's float byte[] = [ z1 z2 z3 z4 ]

Hash code: byte[] {x2^x3 , y2^y3, z2 ^ z3, x2 ^ z3}

或類似的東西...簡而言之-我很好奇如何確保適合我equals方法的向量的哈希碼總是相同的...如果某人對低成本的計算有很好的主意,我會d喜歡聽到它。 或者,如果您可以將我引導到一個更深入地討論浮點數存儲方式的地方,並且如果上述比較方法返回相等的話,哪些字節將始終相同。

我可能需要一種新的比較方法而不是哈希函數,因為實際上我無法確定任何字節都可以匹配我猜...

好吧,基本思想很簡單-您必須人為地降低浮標的精度。 如何有效地做到這一點在很大程度上取決於您期望看到的數據類型。

例如,如果您主要使用較小的值,則可以使用類似以下的內容:

(int)Math.Round(x1 * 1000) 
^ (int)Math.Round(x2 * 1000) 
^ (int)Math.Round(x3 * 1000)

請注意,雖然我實際上並沒有滿足您的if (e < .00001f && e > -.00001f)條件,但這無關緊要-想法是減少沖突,並確保相等的值具有相等的值哈希碼。 不必(或不可能)也確保不相等的值不會具有相等的哈希碼。 其余的應該在Equals==等的重寫中進行處理-這是必須進行嚴格的相等性檢查的地方。 Equals和company不同, GetHashCode() 包含有關單個向量的數據,因此您甚至沒有選擇使用其中多個向量的數據。

哈希碼僅用於使鍵沖突很少發生。 因此,如果您的每個向量在GetHashCode()返回0Dictionary仍然可以使用-只是性能會受到影響。 只要相等的向量以相等的哈希碼結尾,則哈希碼可以是滿足您需求的任何東西:)

當然,最好的方法就是不將向量用作字典中的鍵。 找到向量中您最感興趣的部分(對您最大的幫助),並將其用作鍵。 也許您會發現Dictionary實際上並不是您真正想要的(例如,在游戲中,有大量可用於向量的不同空間分區方法-從簡單的網格狀布局到手動空間分區,直至(例如BSP)。

暫無
暫無

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

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