2016-06-17 12 views
9

इसलिए मैंने हाल ही में भाषा कोटलिन से प्यार करना शुरू कर दिया। आज, युगल की तुलना करते समय, मैं अपरिहार्य NaN पर आया।कोटलिन में NaN की तुलना

fun main(args: Array<String>) { 
    val nan = Double.NaN 
    println("1: " + (nan == nan)) 
    println("2: " + (nan == (nan as Number))) 
    println("3: " + ((nan as Number) == nan)) 
} 

एनबी:

ऊपर कोड पैदावार चल रहा है (DoubleNumberकी एक उप-प्रकार है):

1: false 
2: true 
3: true 

मैं समझता हूँ कि comparing जावा में NaN साथ रिटर्न false , इसलिए मैंकी अपेक्षा करूंगा सभी अभिव्यक्तियों के लिए।

इस व्यवहार को कैसे समझाया जा सकता है? इसके पीछे तर्क क्या है?

उत्तर

8

क्योंकि (2) और (3) एक आदिम मुक्केबाजी का संकलन किया जाता है और फिर Double.equals जांच है कि: JVM पर, आदिम double एक बॉक्स्ड की तुलना नहीं की जा सकती।

Double.equals, बारी में, दो Double के doubleToLongBits(...) तुलना करके समानता की जाँच करता है, और बाद के लिए एक गारंटी है कि तर्क NaN है

हैं, तो परिणाम 0x7ff8000000000000L है नहीं है।

तो, बिट्स के लिए दो NaN बराबर हैं लौट आए, और नियम NaN != NaN यहाँ नजरअंदाज कर दिया है।

इसके अलावा, उल्लेख @miensol के रूप में, वहाँ इस समानता की जांच का एक और परिणाम है: +0 और -0== जांच और equals जांच के लिए नहीं के अनुसार बराबर हैं। जावा में

समतुल्य कोड होगा:

double nan = Double.NaN; 
System.out.println("1: " + (nan == nan)) //false 
System.out.println("2: " + ((Double) nan).equals(((Number) nan))) 
System.out.println("3: " + ((Number) nan).equals(nan)); 

अंतिम दो पंक्तियों फोन Double.equals, doubleToLongBits(...) की तुलना।

+2

मुझे लगता है कि अगर आप से [प्रलेखन] निम्न पंक्ति (https://docs.oracle.com/javase/7/docs/api/java/lang/ उल्लेख अपने जवाब और पूरी होगी Double.html # DoubleToLongBits (डबल)) 'DoubleToLongBits': ** सभी NaN मानों को छोड़कर एक" कैननिकल "NaN मान ** में ध्वस्त हो जाता है। अन्यथा आप सोच सकते हैं कि दो अलग-अलग 'NaN' उस फ़ंक्शन के साथ झूठी तुलना करेंगे। – nfs

+0

@nrohwer, आपकी टिप्पणी के लिए धन्यवाद, उत्तर अपडेट किया गया। – hotkey

7

पहले तुलना जावा के के बराबर है:

double left = Double.NaN; 
double right = Double.NaN; 
boolean result = left == right; 

और जैसा कि आप read in this answer इस Standarized और दस्तावेज व्यवहार कर रहा है कर सकते हैं।

Double left = Double.valueOf(Double.NaN); 
Number right = Double.valueOf(Double.NaN); 
boolean result = left.equals(right); 

कौन सा Double.equals का उपयोग करता है:

दूसरा & तीसरे तुलना के बराबर हैं

ध्यान दें कि ज्यादातर मामलों में, class Double, d1 और d2, के मूल्य के दो उदाहरणों के लिए d1.equals(d2) सत्य है यदि और केवल d1.doubleValue() == d2.doubleValue() के पास भी मूल्य सही है।

  • d1 और d2 दोनों का प्रतिनिधित्व Double.NaN, तो बराबर विधि रिटर्न true, भले ही Double.NaN==Double.NaN मूल्य false है: लेकिन, इसमें दो अपवाद हैं।

  • तो d1 का प्रतिनिधित्व करता है +0.0 जबकि d2-0.0, या इसके विपरीत, बराबर परीक्षण मूल्य false है का प्रतिनिधित्व करता है, भले ही +0.0==-0.0 मूल्य true है।

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