2013-02-08 23 views
29

हाल ही में जावा में एक प्रोजेक्ट लिखा है और डबल/डबल कार्यान्वयन के साथ एक बहुत ही अजीब विशेषता देखी है। जावा में डबल टाइप में दो 0 है, यानी 0.0 और -0.0 (हस्ताक्षर शून्य है)।जावा ने शून्य और मुक्केबाजी

0.0 == -0.0 

true का आकलन करती है, लेकिन: अजीब बात यह है कि है

new Double(0.0).equals(new Double(-0.0)) 

false मूल्यांकन करता है। क्या किसी को इसके पीछे कारण पता है?

+5

इससे बचने का सामान्य तरीका '0.0' जोड़ना है। थोड़ा और विस्तार के लिए [यहां] (http://stackoverflow.com/a/8153449/823393) देखें। – OldCurmudgeon

उत्तर

38

यह सब the javadoc में समझाया गया है:

नोट अगर सच ज्यादातर मामलों में,, डबल d1 और d2, d1.equals (डी 2) का मान वर्ग के दो उदाहरणों के लिए है कि और केवल यदि

d1.doubleValue() == d2.doubleValue() 

भी मूल्य सही है।

  • तो बराबरी विधि सच देता है, भले ही Double.NaN == Double.NaN मूल्य झूठी है d1 और d2 दोनों Double.NaN हैं तो इस तथ्य: हालांकि, इसमें दो अपवाद है।
  • यदि डी 1 +0.0 का प्रतिनिधित्व करता है जबकि डी 2 प्रतिनिधित्व करता है -0.0, या इसके विपरीत, बराबर परीक्षण में मूल्य गलत होता है, भले ही +0.0 == - 0.0 मान सही है।

यह परिभाषा हैश टेबल को ठीक से संचालित करने की अनुमति देती है।


अब आप पूछ सकते हैं क्यों 0.0 == -0.0 सच है। वास्तव में वे सख्ती से समान नहीं हैं। उदाहरण के लिए:

Double.doubleToRawLongBits(0.0) == Double.doubleToRawLongBits(-0.0); //false 

गलत है। हालांकि, JLS की आवश्यकता है ("आईईईई 754 मानक के नियमों के अनुसार ") है कि:

सकारात्मक शून्य और नकारात्मक शून्य बराबर माना जाता है।

इसलिए 0.0 == -0.0 सत्य है।

+2

और जेएलएस की आवश्यकता है क्योंकि आईईईई 754 के लिए इसकी आवश्यकता है। – ninjalj

+1

@ निंजल वास्तव में - उस स्पष्टीकरण को जोड़ा गया। – assylias

-5

== कथन का उपयोग करके आप मूल्यों की तुलना कर रहे हैं। बराबर के साथ आप वस्तुओं की तुलना कर रहे हैं।

2

डबल क्लास में हस्ताक्षरित शून्य का उपयोग करना महत्वपूर्ण है। (अनुभवी जावा प्रोग्रामर के लोड नहीं करते हैं)।

संक्षिप्त उत्तर यह है कि ("परिभाषा के अनुसार)" -0.0 0.0 से कम है "डबल क्लास (यानी, बराबर(), तुलना(), तुलना करने के लिए(), आदि) द्वारा प्रदान की गई सभी विधियों में

डबल सभी फ़्लोटिंग पॉइंट संख्याओं को "एक संख्या रेखा पर पूरी तरह से आदेश दिया जा सकता है" की अनुमति देता है। प्राइमेटिव्स जिस तरह से उपयोगकर्ता चीजों के बारे में सोचेंगे (असली दुनिया परिभाषा) ...0 d = -0d

निम्नलिखित स्निपेट व्यवहार उदाहरण देकर स्पष्ट करना ...

final double d1 = 0d, d2 = -0d; 

System.out.println(d1 == d2); //prints ... true 
System.out.println(d1 < d2); //prints ... false 
System.out.println(d2 < d1); //prints ... false 
System.out.println(Double.compare(d1, d2)); //prints ... 1 
System.out.println(Double.compare(d2, d1)); //prints ... -1 

अन्य संगत पोस्ट कर रहे हैं और अच्छी तरह से पृष्ठभूमि समझाने ...

1 के होते हैं: Why do floating-point numbers have signed zeros?

2: Why is Java's Double.compare(double, double) implemented the way it is?

और सावधानी के एक शब्द ...

आपको लगता है कि पता नहीं है, डबल वर्ग में, "-0.0 कम से कम 0.0 है", तो आप बाहर पकड़े सकता है जब बराबरी की तरह विधि (का उपयोग करते हुए) और तुलना करें() और तुलना करें() तर्क परीक्षण में डबल से। उदाहरण के लिए, पर

final double d3 = -0d; // try this code with d3 = 0d; for comparison 

if (d3 < 0d) {  
    System.out.println("Pay 1 million pounds penalty"); 
} else {   
    System.out.println("Good things happen"); // this line prints 
} 


if (Double.compare(d3, 0d) < 0) { //use Double.compare(d3, -0d) to match the above behaviour 
    System.out.println("Pay 1 million pounds penalty"); // this line prints 
} else {        
    System.out.println("Good things happen"); 
} 

देखो ... और के लिए बराबर होती है आप कोशिश कर सकते हैं ... नई डबल (डी 3) .equals (0 दिन) || नया डबल (डी 3) .equals (-0d)

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