2009-10-30 6 views
19

सी # में निम्नलिखित कोड काम नहीं करता:डबल और इंट की तुलना करने का सबसे अच्छा तरीका क्या है?

int iValue = 0; 
double dValue = 0.0; 

bool isEqual = iValue.Equals(dValue); 

तो, सवाल: क्या डबल और इंट तुलना करने के लिए सबसे अच्छा तरीका क्या है?

+0

इस संबंधित प्रश्न को देखें: Konamiman

+0

[फ्लोट और डबल तुलना के लिए सबसे प्रभावी तरीका क्या है?] (Http: // stackoverflow.com/q/17333/995714) –

उत्तर

44

आप वास्तव में एक बेवकूफ तरीके से फ़्लोटिंग पॉइंट और अभिन्न मूल्यों की तुलना नहीं कर सकते हैं; खासकर, चूंकि क्लासिक floating pointrepresentation challenges है। क्या आप कर सकते हैं दूसरे से घटाना करें और देखें कि उनके बीच के अंतर कुछ सटीक आप के बारे में परवाह है, तो तरह से भी कम है है कार्य करें:

int iValue = 0; 
double dValue = 0.0; 

var diff = Math.Abs(dvalue - iValue); 
if(diff < 0.0000001) // need some min threshold to compare floating points 
    return true; // items equal 

आप वास्तव में क्या equality आप का मतलब खुद के लिए निर्धारित करने की । उदाहरण के लिए, आप एक फ्लोटिंग पॉइंट वैल्यू को निकटतम पूर्णांक की ओर गोल करने के लिए चाहते हैं, ताकि 3.99 99 99 8 9 1 "बराबर" हो। 4. या आप मान को छोटा कर सकते हैं, इसलिए यह प्रभावी रूप से 3 होगा। यह सब आपके पर निर्भर करता है हासिल करने की कोशिश कर रहे हैं।

संपादित करें: ध्यान दें कि मैंने 0.0000001 को उदाहरण थ्रेसहोल्ड मान के रूप में चुना है ... आपको अपने लिए यह तय करने की आवश्यकता है कि तुलना के लिए सटीकता पर्याप्त है। बस आपको एहसास है कि आपको double की सामान्य प्रतिनिधित्व सीमाओं के भीतर होना चाहिए जो मुझे विश्वास है कि Double.Espilon के रूप में परिभाषित किया गया है।

+0

यह मैंने बताई गई समस्या का एक अच्छा समाधान है। अधिक सटीकता के लिए (केवल जब आवश्यक हो), केवल मेरे पूर्णांक का उपयोग करें, जैसा कि मैंने अपने उत्तर में सुझाव दिया था। –

+0

क्या आप 0.0000001 जैसे हार्ड-कोडेड मान के बजाय सिस्टम परिभाषित निरंतर ईपीएसलॉन (यहां http://msdn.microsoft.com/en-us/library/system.double.epsilon.aspx देखें) की तुलना में बेहतर तुलना करेंगे? एनबी मैंने कभी सी # (केवल सी ++) कोड नहीं किया है, लेकिन मुझे लगता है कि उसी सिद्धांत पर लागू होता है – pxb

+1

मैं उल्लेख करता हूं कि मेरे उत्तर में संपादन में। ओपीलॉन अपने कोड में क्या सटीकता की परवाह करता है इसके आधार पर एक अच्छा विकल्प हो सकता है या नहीं भी हो सकता है। – LBushkin

1

यह वास्तव में "बराबर" पर विचार करता है। आप अगर और सिर्फ़ अगर डबल ठीक पूर्णांक मान से मेल खाता अपनी तुलना सही वापस जाने के लिए (यानी कोई आंशिक घटक है), तो आप तुलना करने के लिए एक डबल करने के लिए अपने पूर्णांक डाली चाहिए चाहते हैं:

bool isEqual = (double)iValue == dValue; 

कुछ की तरह हैं 1.1 को 1 के बराबर माना जाएगा, आप या तो डबल को एक int (यदि आप आंशिक घटक को पूरी तरह से अनदेखा करना चाहते हैं) या दो बार गोल करना चाहते हैं, तो यदि आप 1.9 से बराबर 2.

+0

हालांकि, गोल करने के साथ सावधान। बहुत से लोग आश्चर्यचकित होते हैं जब 2.5 राउंड से 2. – Joey

+0

@ जॉय अपने स्वयं के राउंडिंग कोड को लिखने के लिए बहुत ही छोटा है, यदि आप चाहते हैं कि तीन अंतर्निहित आपकी आवश्यकताओं को पूरा न करें। – Casey

3

यह एक बहुत बुरा विचार है किसी भी भाषा में समानता के लिए पूर्णांक और फ़्लोटिंग-पॉइंट संख्याओं की तुलना करने के लिए। यह बहुत ही साधारण मामलों के लिए काम करता है, लेकिन जब आप किसी भी गणित को पूरा करते हैं, तो प्रोग्राम की पसंद जो आप चाहते हैं वह नाटकीय रूप से घट जाती है।

इसे फ्लोटिंग-पॉइंट नंबरों को बाइनरी, डिजिटल सिस्टम पर संग्रहीत करने के तरीके से करना है।

यदि आप सुनिश्चित हैं कि आप इसका उपयोग करना चाहते हैं, तो आप को अपनी संख्या को भिन्नता के साथ बनाने के लिए एक वर्ग बनाएं। पूरे नंबर को बनाए रखने के लिए एक int का उपयोग करें, और अंश को बनाए रखने के लिए एक और int।

0

आजकल, बस केवल समय के बारे में एक प्रकार double और या तो integer या long सख्त समानता के लिए के मूल्यों की तुलना होना चाहिए जब किसी कारण से, एक अटक भंडारण या फ्लोटिंग प्वाइंट मूल्यों और बाद में की जरूरत के रूप में अभिन्न मात्रा गुजर है उन्हें वापस बदलने के लिए। इस तरह के रूपांतरण ज्यादातर मामलों में अभिन्न प्रकार को double पर कास्ट करके और उस कलाकार के परिणाम की तुलना करके सबसे आसानी से पूरा किया जा सकता है। ध्यान दें कि long से double पर रूपांतरण अपर्याप्त हो सकता है यदि संख्या ± 2 सीमा से बाहर है। फिर भी, 64-बिट long से पहले के दिनों में उपलब्ध हो गया, double पूर्णांक मात्रा के लिए एक आसान भंडारण प्रकार था जो 32-बिट int के लिए बहुत बड़ा था, लेकिन double द्वारा संभाला जाने वाला छोटा छोटा था।

ध्यान दें कि एक longdouble के लिए और फिर कर तुलना एक "बराबर" परिणाम उपज अगर double के अंकित मूल्य ठीक long मूल्य से मेल नहीं खाता होगा, लेकिन का प्रतिनिधित्व करता है निकटतम संभव double कि मूल्य में कनवर्ट। यह व्यवहार समझ में आता है अगर कोई यह मानता है कि फ़्लोटिंग-पॉइंट प्रकार वास्तव में एक सटीक मान का प्रतिनिधित्व नहीं करते हैं, बल्कि मूल्यों की एक श्रृंखला का प्रतिनिधित्व करते हैं।

2
double val1 = 0; 
double val2 = 0.0; 
if((val1 - Double.Epsilon) < 0) 
{ 
    // Put your code here 
} 

     OR 

if((val2 - Double.Epsilon) < 0) 
{ 
    // Put your code here 
} 

जहां Double.Epsilon डबल के लिए सबसे कम संभव मूल्य है।

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

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