2013-03-22 11 views
15

सटीक समानता के लिए दो फ़्लोटिंग पॉइंट मान की तुलना करने का एक सुरुचिपूर्ण, पठनीय और गैर-वर्बोज़ तरीका क्या है?सटीक समानता के लिए दो फ्लोट/डबल मानों की जांच करें

जितना आसान हो सकता है उतना आसान, यह एक दुष्ट समस्या है। == ऑपरेटर काम NaN के लिए करवाने नहीं है और भी शून्य के लिए विशेष उपचार है:

(+0.0 == -0.0) -> true 
Double.NaN == Double.NaN -> false 

लेकिन मैं निर्धारित करने के लिए दो मान बिल्कुल एक जैसे हैं चाहते हैं (लेकिन मैं अलग NaN के लिए नहीं देखभाल करना पैटर्न, तो कोई भी NaN == कोई अन्य NaN -> सत्य)।

मैं कोड के इस बदसूरत राक्षस टुकड़े के साथ ऐसा कर सकते हैं:

Double.doubleToLongBits(a) == Double.doubleToLongBits(b) 

वहाँ एक बेहतर तरीका यह लिखने के लिए (और इरादे स्पष्ट कर) है?

+0

आप ऐसा नहीं करते कि आप ऐसा क्यों करना चाहते हैं। यदि वे वास्तव में फ़्लोटिंग पॉइंट नंबर हैं तो आपका उत्तर सार्थक नहीं होगा। – Julian

+0

@ जुलिएन पीटर उदाहरण के लिए पीटरलावरी का जवाब देखें जहां यह बहुत सार्थक है। मेरा आवेदन हालांकि किसी ऑब्जेक्ट की बराबर() विधि है जहां एक फ्लोट प्राथमिक कुंजी का हिस्सा है (मेरी पसंद से नहीं)। फ़्लोटिंग पॉइंट आमतौर पर अंतर्ज्ञानी धारणाओं को खारिज कर देता है, इसलिए मैं किनारे के मामलों को कवर करने के लिए सावधान हूं। – Durandal

+0

क्षमा करें, आप इसे बेहतर नहीं कर सके, आपका "बदसूरत राक्षस टुकड़ा" पहले से ही सही है ... –

उत्तर

10

जो आपको मिला है वह पहले से ही करने का सबसे अच्छा तरीका है, मैं कहूंगा। यह स्पष्ट करता है कि आप बिटवाई मूल्य का प्रतिनिधित्व करने में रुचि रखते हैं। आप उन बिट्स को long पर एक सुविधाजनक 64-बिट प्रकार के रूप में परिवर्तित करना चाहते हैं, जिसमें कोई फर्क नहीं पड़ता है।

आप इसे अपने codebase में अक्सर दिखाई दे रहा नहीं करना चाहते हैं, बस इसे रैप करने के लिए एक पद्धति जोड़ें:

public static boolean bitwiseEqualsWithCanonicalNaN(double x, double y) { 
    return Double.doubleToLongBits(x) == Double.doubleToLongBits(y); 
} 

ध्यान रखें कि आपके प्रश्न के अनुसार, यह करता है अलग NaN मूल्यों के बीच नहीं अंतर करें। यदि आप बाद की तारीख में ऐसा करना चाहते हैं, तो आपको Double.toRawLongBits का उपयोग करना होगा।

+0

मिह, आपके और पीटर दोनों के जवाब में उनकी अपील है। स्पष्टता के लिए मुझे लगता है कि स्थैतिक सहायक थोड़ा बेहतर है, क्योंकि मैं सिर्फ इस विधि पर अपनी टिप्पणी डाल सकता हूं और कॉल पर आने वाले किसी भी व्यक्ति वहां पहुंच जाएगा। फिर भी एक अच्छा विधि नाम के बारे में सोच रहा है। – Durandal

22

आप

Double.compare(a, b) == 0 

जावाडोक से compareTo

के लिए उपयोग कर सकते हैं
  • Double.NaN इस विधि द्वारा माना जाता है खुद के बराबर और (Double.POSITIVE_INFINITY सहित अन्य सभी डबल मूल्यों से अधिक होना)।
  • 0.0 डी इस विधि द्वारा -0.0 डी से अधिक होने के लिए माना जाता है।
+0

क्या यह दो 0s के बीच भी अंतर करेगा? –

+0

यह NaNs करेगा। -0 और 0 –

+1

के लिए जांच कर रहा है मैंने अभी जांच की है। ऐसा होता है। अच्छा - हालांकि नहीं * स्पष्ट रूप से * सही, मैं कहूंगा। (मैं सहजता से * अपेक्षित * होगा कि दावा करने के लिए कि सकारात्मक और नकारात्मक शून्य बराबर हैं। मैं कोड पसंद करता हूं जो इसे स्पष्ट रूप से स्पष्ट करता है कि आप सटीक बिट्स में रूचि रखते हैं।) –

संबंधित मुद्दे