2013-05-08 29 views
5

Tôi có vấn đề lạ và tôi không có đầu mối để theo dõi lý do. Tôi sẽ cố gắng mô tả rõ ràng vấn đề của tôi.Sự cố IComparer

Tôi đã một lớp RTree, trong lớp này, tôi muốn so sánh hai rectanlge (ở đây tôi gọi là phong bì, nó chứa MINX, MINY, Maxx, MAXY), vì vậy chúng tôi có một lớp Comparer như sau:

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; 
    } 
} 

Với bộ so sánh này, chúng tôi có thể duy trì một ArrayList của phong bì và sắp xếp nó một cách dễ dàng, các phong bì được thêm vào ngẫu nhiên. Khi chúng tôi gọi mã sau đây và chúng tôi đã gặp số

Không thể sắp xếp vì phương thức IComparer.Compare() trả về kết quả không phù hợp . Giá trị không so sánh với chính nó, hoặc một giá trị nhiều lần so với giá trị khác mang lại kết quả khác nhau .

sortedChildBoundables.Sort(new AnonymousXComparerImpl()); 

Dưới đây là phần kỳ lạ. Lỗi này chỉ xảy ra trong .net 4.0 không cài đặt VistualStudio. Nếu máy đã cài đặt VS hoặc .net 4.5, vấn đề này không thể tái chế lại.

Trong trường hợp này, tôi không thể hiểu tại sao điều đó xảy ra. Nó sẽ là tuyệt vời nếu bạn có bất kỳ kinh nghiệm về gỡ lỗi loại vấn đề, tôi đánh giá cao.

Xin cảm ơn, Howard

+0

Điều duy nhất tôi có thể nghĩ đến ở đây là vấn đề điểm nổi có nghĩa là bình đẳng không hoàn toàn phù hợp cho cùng một mục, không có ý tưởng tại sao nó sẽ được cụ thể cho v4. Bạn đã thử thực hiện một mức độ làm tròn? –

+0

Hãy thử sử dụng kiểu dữ liệu 'thập phân 'thay vì số double – Saravanan

+0

Không có chủ đề nào khác có liên quan? Ngoài ra, chủ đề này có thể được quan tâm: http://stackoverflow.com/questions/6683059/are-floating-point-numbers-consistent-in-c-can-they-be –

Trả lời

5

Nếu ví dụ: ea.MinXNaN, a sẽ là NaN và cả hai a > ba < b sẽ là false. Điều này có nghĩa, có những đối tượng so sánh với mọi đối tượng khác.

Trước tiên, bạn phải quyết định cách bạn muốn các đối tượng chứa NaN được sắp xếp.

An dễ workaround có thể là để chèn

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

Theo ghi nhận của @Seph và @Jeppe trong ý kiến, double.CompareTo làm điều đúng đắn, vì vậy dòng cuối cùng có thể được thay thế bằng return a.CompareTo(b);.

+0

+1 Điều này nghe có vẻ hợp lý - mặc dù tôi không chắc tại sao kết quả lại khác nhau giữa các phiên bản .Net. Nhưng nếu có * có thể * là NaN trong dữ liệu (và OP nói có thể) thì chắc chắn nó sẽ gây ra loại vấn đề đã được quan sát. –

+0

Điều đó có ý nghĩa, vui lòng cho phép tôi giữ chuỗi này trong một thời gian và đánh dấu là câu trả lời sau. Cảm ơn bạn rất nhiều. – Howard

+2

@MatthewWatson - có thể chức năng 'Sắp xếp' trong phiên bản mới không thực hiện các so sánh không cần thiết và do đó không thể phát hiện sự mâu thuẫn. – Henrik

0

Một nguyên nhân có thể là thông tin của bạn thực sự bị thay đổi trong quá trình so sánh.

Nếu bạn sắp xếp theo chủ đề nền, chắc chắn bạn sẽ gặp phải lỗi này nếu so sánh nhận được các giá trị khác nhau cho cùng một mục khi yêu cầu nó hai lần.

Nếu chủ đề chính của bạn cập nhật một trong các giá trị (có thể bằng cách kết nối dữ liệu) trong khi so sánh chạy chẳng hạn.

Đảm bảo bạn lưu trữ giá trị so sánh để bạn luôn trả về kết quả nhất quán. Hoặc chấp nhận rằng lỗi có thể xảy ra theo thời gian và làm lại sắp xếp nếu có.

Điều này cũng sẽ giải thích cảm giác của bạn về sự phụ thuộc máy/os. Vấn đề đa luồng xảy ra khác nhau tùy thuộc vào sự khác biệt phần mềm và phần cứng.