2013-08-11 3 views
7

के बीच प्रकार कास्टिंग मैं इस कोडअप्रत्याशित परिणाम हो रही है लंबे और डबल

public class LimitTest{ 
    public static void main(String[] args){ 
     long l; 
     double d; 
     l = 9223372036854775807L;// The largest number a long can hold. 
     d = l; 
     System.out.println(l); 
     System.out.println(d); 
     System.out.println(l == d); 
    } 
} 

अब जब, परिणाम यह पैदा करता थोड़े अप्रत्याशित है, लेकिन फिर से, मैं बहुत प्रकार रूपांतरण के साथ अनुभव नहीं कर रहा हूँ।

आउटपुट

9223372036854775807 
9.223372036854776E18 
true 

अब, मुद्रित दो नंबर स्पष्ट रूप से कर रहे हैं बराबर नहीं, तो क्यों करता है l == d वापसी true?

उत्तर

5

चर l और d, विभिन्न प्रकार है, इसलिए अभिव्यक्ति long == double एक double करने के लिए long डाले ...

पी.एस. l एक खराब वैरिएबल नाम imho है, क्योंकि यह कोड पर चमकते समय 1 जैसा दिखता है।

2

तो क्यों एल == सच लौट d करता है:

आप रुचि रखते हैं, तो आप अप JLS में पदोन्नति नियमों पर पढ़ सकते हैं ;

क्योंकि long तुलना से पहले double में बदल जाती है। और इसलिए परिणाम सच है।

यह JLS - Section 5.6.2 में निर्दिष्ट किया जाता:

आदिम रूपांतरण (§5.1.2) चौड़ा लागू किया जाता है परिवर्तित करने के लिए एक या दोनों ऑपरेंड के रूप में निम्नलिखित नियमों द्वारा निर्दिष्ट:

  • या तो संकार्य है डबल टाइप करें, दूसरा डबल में परिवर्तित हो जाता है।

आप double के लिए अलग परिणाम देख रहे हैं, क्योंकि सभी long मूल्यों एक अनूठा double मान से दर्शाया जा सकता है। तो, आपके पास एक लंबे मूल्य के लिए संभवतः कई डबल मान हो सकते हैं। long से double में कनवर्ट करते समय परिशुद्धता का संभावित नुकसान होता है।

JLS Section 5.1.2 से

:

एक पूर्णांक या एक लंबी मूल्य फ्लोट करने के लिए, या एक लंबे मूल्य की का एक चौड़ा रूपांतरण दोगुना करने के लिए, सटीक की हानि हो सकती है - जो है, परिणाम खो सकते हैं मूल्य के कम से कम महत्वपूर्ण बिट्स में से कुछ।

2

दो मानों की तुलना करने के लिए उनके पास एक ही प्रकार होना चाहिए। यहां लंबा मूल्य दोहरा प्रकार में परिवर्तित हो गया है, और रूपांतरण का परिणाम एक असाइनमेंट के समान मूल्य देता है।

मूल्य पहले स्थान पर अलग हैं क्योंकि डबल प्रकार के पास "महत्व" कम है (इसमें वास्तविक अंकों को संग्रहीत करने के लिए 53 बिट मंटिसा है; शेष बिट्स का उपयोग साइन और एक्सपोनेंट के लिए किया जाता है) लंबे समय से (सभी 64 बिट्स)। सभी लंबे मूल्यों को एक अद्वितीय डबल मान के रूप में प्रदर्शित नहीं किया जा सकता है।

2

9223372036854775807 और 9.223372036854776E18हैं समान

नोट परिशुद्धता 922337203685477 के पहले 15 अंक ही हैं। शेष पहले नंबर 5807 को 6 तक गोल किया जाता है ताकि E18 जोड़ा जा सके।

वैज्ञानिक अंकन में 9223372036854775807 है:

9.223372036854775807 x 10^18 == 9.223372036854775807E18 

की तुलना करें:

9.223372036854775807E18 
9.223372036854776E18 

मूल्य अधिक परिशुद्धता की तुलना में यह साथ प्रदर्शित किया जाता है के साथ संग्रहीत किया जाता है, इस सबूत के लिए देखें:

long l; 
    double d; 
    l = Long.MAX_VALUE;// The largest number a long can hold. 
    d = l; //This is implicitly cast to (double) 
    System.out.println("long: " + l); 
    System.out.println("double: " + d); 
    System.out.println("double back to long: " + (long) d); 

लंबे: 9223372036854775807
डबल: 9.223372036854776E18
डबल वापस लंबा करने के लिए: 9223372036854775807

भी कैसे तैरता और युगल जमा हो जाती है के माध्यमिक समस्या है। जबकि पूर्णांक प्रकार (बाइट, शॉर्ट, इंट, लांग) सटीक, फ्लोट और डबल आईईईई 754 मंटिसा-एक्सपोनेंट शैली का उपयोग करते हैं जो उन्हें संख्याओं की एक विस्तृत श्रृंखला का प्रतिनिधित्व करने की अनुमति देता है लेकिन कम परिशुद्धता के साथ। http://en.wikipedia.org/wiki/IEEE_754-1985

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