2012-04-09 19 views
20

यदि मैं double के साथ काम कर रहा हूं, और मैं इसे float में बदलता हूं, तो यह वास्तव में कैसे काम करता है? क्या मूल्य कम हो जाता है, तो यह एक फ्लोट में फिट बैठता है? या क्या मूल्य अलग-अलग हो जाता है? क्षमा करें अगर यह थोड़ा उपचारात्मक लगता है, लेकिन मैं float और double रूपांतरणों की अवधारणा को समझने की कोशिश कर रहा हूं।जावा में डबल से फ्लोट में कनवर्ट करना

+0

http://stackoverflow.com/a/2781125/986169 – giorashc

उत्तर

19

Java Language Specification, section 5.1.3 से:

फ्लोट करने के लिए डबल से एक संकुचन आदिम रूपांतरण आईईईई 754 गोलाई नियमों से संचालित किया जाता है (§4.2.4)। यह रूपांतरण परिशुद्धता खो सकता है, लेकिन रेंज भी खो सकता है, जिसके परिणामस्वरूप एक गैर-शून्य डबल से एक फ्लोट शून्य और एक सीमित डबल से एक फ्लोट अनंतता होती है। एक डबल नाइन एक फ्लोट NaN में परिवर्तित हो जाता है और एक डबल इन्फिनिटी को उसी हस्ताक्षरित फ्लोट अनंतता में परिवर्तित कर दिया जाता है।

और section 4.2.4 का कहना है:

जावा प्रोग्रामिंग भाषा है कि व्यवहार के रूप में यदि हर फ्लोटिंग प्वाइंट ऑपरेटर परिणाम परिशुद्धता के लिए अपनी फ्लोटिंग प्वाइंट परिणाम गोल फ्लोटिंग प्वाइंट गणित की आवश्यकता है। अचूक परिणाम असीमित सटीक परिणाम के नजदीकी प्रतिनिधित्व मूल्य के लिए गोलाकार होना चाहिए; यदि दो निकटतम प्रतिनिधित्व योग्य मान समान रूप से निकट हैं, तो कम से कम महत्वपूर्ण बिट शून्य वाला एक चुना जाता है। यह आईईईई 754 मानक का डिफ़ॉल्ट गोलाकार मोड है जो निकटतम के रूप में जाना जाता है।

+0

इसके लिए धन्यवाद। मैंने देखा कि यह निकटतम में आईईईई 754 दौर के उपयोग का उल्लेख करता है। क्या एक अलग गोल मोड निर्दिष्ट करने के लिए वैसे भी है? – Franklin

+0

@ फ्रैंकलिन: एक ['RoundingMode'] है (http://docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html) कक्षा, लेकिन मुझे लगता है कि केवल 'BigDecimal' पर लागू होता है और 'BigInteger' संचालन, primitives पर संचालन के लिए नहीं। लेकिन मैं उस पर 100% आत्मविश्वास नहीं हूं। –

+1

जावा केवल एक एफपी राउंडिंग मोड का समर्थन करता है - अधिक वर्षों पहले (ज्यादातर एचपीसी समुदाय के लिए, यानी denlock को संभालने के बारे में भी इत्यादि) के बारे में कुछ बात थी, लेकिन हां, जो कहीं भी नहीं गए थे। – Voo

8

मैं सुझाव दूंगा कि फ़्लोटिंग-पॉइंट प्रकारों को सबसे अधिक मूल्यवान मानों के प्रतिनिधित्व के रूप में माना जाता है। 0.100000001490116119384765625 के बजाय 0.1f 0.1 के रूप में प्रदर्शित होने का कारण यह है कि यह वास्तव में 13421772.5/134217728 से 13421773.5/134217728 (यानी 0.099 99 99977648258209228515625 से 0.1000000052154064178466796875) तक की संख्या का प्रतिनिधित्व करता है; यह इंगित करने के लिए अतिरिक्त अंक जोड़ने का अर्थ नहीं होगा कि यह संख्या 0.100 से अधिक हो सकती है जब यह कम हो सकती है, न ही नैनों की एक स्ट्रिंग का उपयोग करने के लिए संकेत मिलता है कि यह संख्या 0.100 से कम हो सकती है जब यह अधिक हो सकती है।

एक फ्लोट के लिए डबल कास्टिंग फ़्लोट का चयन करेगा, जिसमें मूल्यों की श्रेणी में डबल द्वारा प्रतिनिधित्व किए गए युगल की श्रृंखला शामिल है। ध्यान दें कि यह ऑपरेशन गैर-परिवर्तनीय है, लेकिन ऑपरेशन का परिणाम आमतौर पर अंकगणितीय रूप से सही होगा; एकमात्र समय यह 100% अंकगणितीय रूप से सही नहीं होगा यदि कोई एक डबल फ्लोट करने के लिए कास्टिंग कर रहा था, जिसकी सीमा दो फ्लोट्स के बीच सीमा पर केंद्रित थी। उस स्थिति में, प्रणाली एक तरफ या डबल की सीमा के दूसरे पर फ्लोट का चयन करेगी; यदि वास्तव में डबल ने सीमा के गलत पक्ष पर एक संख्या का प्रतिनिधित्व किया, तो परिणामी रूपांतरण थोड़ा गलत होगा।

प्रैक्टिस में, उपर्युक्त वर्णित छोटा अपर्याप्तता लगभग कभी प्रासंगिक नहीं है, क्योंकि फ्लोटिंग-पॉइंट प्रकार द्वारा प्रतिनिधित्व की जाने वाली "मानों की रेंज" उपरोक्त संकेत से थोड़ा बड़ा है। एक निश्चित मात्रा में अनिश्चितता के साथ दो अंकों पर एक गणना (जैसे जोड़) करना, परिणामस्वरूप अधिक अनिश्चितता के साथ परिणाम मिलेगा, लेकिन सिस्टम इस बात पर नज़र रखेगा कि कितनी अनिश्चितता मौजूद है। फिर भी, जब तक कि कोई एक फ्लोट पर हजारों परिचालन नहीं करता है, या दो बार संचालन के हजारों ऑपरेशन करता है, तो अनिश्चितता की मात्रा आमतौर पर चिंता करने के लिए पर्याप्त छोटी होगी।

यह ध्यान रखना महत्वपूर्ण है कि एक डबल पर एक फ्लोट कास्टिंग करना वास्तव में दोहरी फ्लोट करने की तुलना में कहीं अधिक खतरनाक ऑपरेशन है, भले ही जावा पूर्व में चेतावनी के बिना पूर्व में अनुमति देता है लेकिन बाद में squawks। एक फ्लोट को डबल करने के लिए सिस्टम को डबल का चयन करने का कारण बनता है, जिसकी सीमा फ्लोट की सीमा के केंद्र के केंद्र में केंद्रित होती है। यह लगभग हमेशा एक मूल्य में परिणाम देगा जिसके वास्तविक अनिश्चितता डबल-परिशुद्धता संख्याओं की तुलना में कहीं अधिक है। उदाहरण के लिए, यदि कोई 0 रहता है।1 एफ से दोगुना, परिणामस्वरूप डबल 0.10000000149011611 से 0.10000000149011613 तक की संख्या का प्रतिनिधित्व करेगा, भले ही यह संख्या (दसवीं) का प्रतिनिधित्व करने वाला नंबर अपेक्षाकृत बोल रहा हो, उस सीमा के पास कहीं भी नहीं।

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