2013-05-08 38 views
5

Mam dziwny problem i nie mam pojęcia, jak go rozpoznać. Postaram się wyraźnie opisać mój problem.Wydanie IComparer

Mam klasy R-drzewo, w tej klasie, chcę porównać dwa rectanlge (tutaj Zadzwoniłem koperta, zawiera Minx, miny, Maxx, maxy), więc mamy klasę comparer następująco:

private class AnonymousXComparerImpl : IComparer 
{ 
    public AnonymousXComparerImpl() 
    { } 

    public int Compare(object o1, object o2) 
    { 
     IEnvelope ea = (IEnvelope)((IBoundable)o1).Bounds; 
     IEnvelope eb = (IEnvelope)((IBoundable)o2).Bounds; 
     double a = (ea.MinX + ea.MaxX)/2d; 
     double b = (eb.MinX + eb.MaxX)/2d; 
     return a > b ? 1 : a < b ? -1 : 0; 
    } 
} 

Dzięki temu narzędziu możemy zachować ArrayList of envelope i łatwo sortować, koperty są losowo dodawane. Kiedy wzywamy poniższy kod i spotkaliśmy

Nie można sortować ponieważ metoda IComparer.Compare() zwraca wyniki niespójne. Wartość nie równa się sama sobie, lub jedna wartość wielokrotnie w porównaniu do innej wartości daje różne wyniki .

sortedChildBoundables.Sort(new AnonymousXComparerImpl()); 

Oto dziwne część. Ten błąd występuje tylko w .net 4.0, który nie instaluje VistualStudio. Jeśli na maszynie zainstalowano VS lub .net 4.5, problemu nie można powtórzyć ponownie.

W tym przypadku nie wiem, dlaczego tak się dzieje. Będzie świetnie, jeśli masz jakieś doświadczenie w debugowaniu tego rodzaju problemów, doceniam.

Dzięki, Howard

+0

Jedyne, co mogę tu wymyślić, to kwestie zmiennoprzecinkowe, co oznacza, że ​​równość nie pasuje do tych samych elementów, nie ma pojęcia, dlaczego byłby on właściwy dla wersji 4. Czy próbowałeś egzekwować poziom zaokrąglania? –

+0

Spróbuj użyć typu danych "dziesiętny' zamiast podwójnego – Saravanan

+0

. Nie ma żadnych innych wątków? Również ten wątek może być interesujący: http://stackoverflow.com/questions/6683059/are-floating-point-numbers-consistent-in-c-can-they-be –

Odpowiedz

5

Jeśli na przykład ea.MinX jest NaN, a będzie NaN i oba a > b i a < b będą . Oznacza to, że istnieją obiekty, które są porównywalne do wszystkich innych obiektów.

Najpierw musisz zdecydować, w jaki sposób posortować obiekty zawierające NaN.

Łatwym Rozwiązaniem może być, aby wstawić

if (double.IsNaN(a)) a = 0.0; 
if (double.IsNaN(b)) b = 0.0; 

Jak zauważył @Seph i @Jeppe w komentarzach, double.CompareTo robi słusznie, więc ostatnia linia może być zastąpiony przez return a.CompareTo(b);.

+0

+1 To brzmi wiarygodne - chociaż nie jestem pewien, dlaczego wyniki będą się różnić między wersjami .Net. Jeśli jednak dane * mogą * być NaNs w danych (a OP mówi, że może), to z pewnością spowoduje to rodzaj problemu, który został zaobserwowany. –

+0

To ma sens, proszę pozwolić mi trzymać ten wątek przez chwilę i oznaczyć jako odpowiedź później. Dziękuję bardzo. – Howard

+2

@MatthewWatson - może funkcja 'Sortuj' w nowej wersji nie robi niepotrzebnych porównań i dlatego nie może wykryć niespójności. – Henrik

0

Jednym z prawdopodobnych powodów jest to, że informacje są faktycznie zmieniane podczas porównywania.

Jeśli dokonasz sortowania w wątku tła, na pewno otrzymasz ten błąd, jeśli porównanie uzyska różne wartości dla tego samego produktu, gdy poprosisz o niego dwa razy.

Jeśli twój główny wątek aktualizuje jedną z wartości (być może przez wiązanie danych), podczas gdy porównanie działa na przykład.

Upewnij się, że buforujesz porównywane wartości, aby zawsze zwracać spójne wyniki. Lub zaakceptuj, że błąd może się zdarzyć od czasu do czasu i ponów sortowanie, jeśli tak się stanie.

To również wyjaśni twoje poczucie zależności między komputerem a ossem. Wielowątkowe problemy występują w różny sposób w zależności od różnic sprzętowych i sprzętowych.