2010-01-11 13 views
17

अंतर्निहित बिट्स को केवल एक फ़्लोटिंग पॉइंट मान के रूप में "पुन: परिभाषित" मिलता है? या निकटतम फ़्लोटिंग पॉइंट मान का उत्पादन करने के लिए एक रन-टाइम रूपांतरण है?सी ++ में क्या होता है जब एक पूर्णांक प्रकार को फ़्लोटिंग पॉइंट प्रकार या इसके विपरीत में डाला जाता है?

क्या किसी भी प्लेटफॉर्म पर अंतहीनता एक कारक है (यानी, फ्लोट्स की अंतहीनता इनट्स से अलग होती है)?

विभिन्न चौड़ाई प्रकार कैसे व्यवहार करते हैं (उदाहरण के लिए, int int को int int करने के लिए int)?

ऐसे मानक/रूपांतरणों की सुरक्षा के बारे में भाषा मानक गारंटी क्या है? कास्ट करके, मेरा मतलब है एक static_cast या सी-शैली कास्ट।

इंट रूपांतरण (या डबल से इंट) में व्यस्त फ्लोट के बारे में क्या? यदि एक फ्लोट में एक छोटा परिमाण मान होता है (उदाहरण के लिए, 2), क्या बिट पैटर्न का अर्थ एक ही अर्थ है जब int के रूप में व्याख्या की जाती है?

+2

पढ़ें * §4.9 - फ़्लोटिंग-अभिन्न रूपांतरण *। –

+0

मैं मानता हूं कि इस प्रश्न का उत्तर स्वयं शोध द्वारा दिया जाना चाहिए: डी हमें पेस्ट मानकों और सीपीयू मैनुअल की प्रतिलिपि बनाना होगा: डी –

+0

@StringRay: http://stackoverflow.com/questions/81656/where-do-i-find-the -कुरेंट-सी-या-सी-मानक-दस्तावेज –

उत्तर

10

क्या अंतर्निहित बिट्स को केवल एक फ़्लोटिंग पॉइंट मान के रूप में "पुन: परिभाषित" मिलता है?

नहीं, मान मानक में नियमों के अनुसार परिवर्तित किया गया है।

क्या निकटतम फ़्लोटिंग पॉइंट मान उत्पन्न करने के लिए एक रन-टाइम रूपांतरण है?

हां एक रन-टाइम रूपांतरण है।

फ़्लोटिंग पॉइंट के लिए -> पूर्णांक, मान छोटा कर दिया गया है, बशर्ते स्रोत मान पूर्णांक प्रकार की सीमा में हो। यदि ऐसा नहीं है, व्यवहार अपरिभाषित है। कम से कम मुझे लगता है कि यह स्रोत मूल्य है, परिणाम नहीं, यह महत्वपूर्ण है। मुझे यह सुनिश्चित करने के लिए देखना होगा। सीमा का मामला यदि लक्ष्य प्रकार चार है, तो कहें, CHAR_MAX + 0.5 होगा। मुझे लगता है कि यह चारों ओर डालने के लिए अनिर्धारित है, लेकिन जैसा कि मैंने कहा है कि मैं निश्चित नहीं हूं।

पूर्णांक के लिए -> फ़्लोटिंग पॉइंट, परिणाम संभव होने पर सटीक वही मान है, या फिर दो फ़्लोटिंग पॉइंट मानों में से एक पूर्णांक मान के दोनों तरफ है। जरूरी नहीं कि दोनों के नजदीक।

क्या किसी भी प्लेटफॉर्म पर अंतहीनता एक कारक है (यानी, फ्लोट्स की अंतहीनता इनट्स से अलग होती है)?

नहीं, कभी नहीं। रूपांतरण मूल्यों के संदर्भ में परिभाषित किए जाते हैं, भंडारण प्रतिनिधित्व नहीं।

विभिन्न चौड़ाई प्रकार कैसे व्यवहार करते हैं (उदाहरण के लिए, int int को int int करने के लिए int)?

सभी महत्वपूर्ण बातों के प्रकार और सटीक हैं।32 बिट इन्ट्स और आईईईई 32 बिट फ्लोट मानते हुए, एक अंतर-> फ्लोट रूपांतरण को कम करने के लिए संभव है। 64 बिट आईईईई युगल मानते हुए, एक int-> डबल रूपांतरण को कम करने के लिए संभव नहीं है, क्योंकि सभी int मानों को वास्तव में डबल के रूप में दर्शाया जा सकता है।

ऐसे मानक/रूपांतरणों की सुरक्षा के बारे में भाषा मानक गारंटी क्या है? कास्ट करके, मेरा मतलब है एक static_cast या सी-शैली कास्ट।

ऊपर बताए अनुसार, यह उस स्थिति को छोड़कर सुरक्षित है जहां एक फ़्लोटिंग पॉइंट मान को पूर्णांक प्रकार में परिवर्तित किया जाता है, और मान गंतव्य प्रकार की सीमा से बाहर है।

यदि एक फ्लोट में एक छोटा परिमाण मान (उदाहरण के लिए, 2) होता है, तो क्या बिट पैटर्न का अर्थ एक इंट के रूप में समझा जाता है?

नहीं, ऐसा नहीं है। आईईईई 32 बिट 2 का प्रतिनिधित्व 0x40000000 है।

2

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

जब आप एक फ्लोट को एक int में परिवर्तित करते हैं तो आप अनिवार्य रूप से फर्श() ऑपरेशन कर रहे हैं। तो यह सिर्फ चल बिन्दु के बारे में अधिक जानकारी को पढ़ने के लिए दशमलव

के बाद बिट्स चला जाता है: http://www.lahey.com/float.htm

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

तो यदि आपका पूर्णांक 24 बिट्स (छुपे हुए प्रमुख बिट को छोड़कर) का उपयोग करता है, तो आप रूपांतरण में कुछ सटीकता खोने की संभावना रखते हैं।

+0

मुझे लगता है कि आपकी पहली वाक्य "... एक फ्लोट के लिए एक पूर्णांक ..." –

+0

धन्यवाद, मैंने इसे ठीक किया। – zmbush

+0

@Stingray: हाँ, एक छंटनी: "रूपांतरण truncates; है कि, आंशिक हिस्सा त्याग दिया जाता है।" –

5

संदर्भ के लिए, यह है कि क्या आईएसओ आईईसी 14,882-2003 का कहना है

4,9 फ्लोटिंग-अभिन्न रूपांतरण

एक चल बिन्दु प्रकार का एक rvalue एक पूर्णांक के एक rvalue में बदला जा सकता है प्रकार। रूपांतरण छंटनी; यानी, आंशिक भाग को त्याग दिया जाता है। व्यवहार को अपरिभाषित किया जाता है यदि गंतव्य प्रकार में छंटनी मूल्य का प्रतिनिधित्व नहीं किया जा सकता है। [नोट: यदि गंतव्य प्रकार `बूल है, तो 4.12 देखें। ]

एक पूर्णांक प्रकार या एक गणना प्रकार का एक रावलू फ़्लोटिंग पॉइंट प्रकार के एक रावल्यू में परिवर्तित किया जा सकता है। यदि संभव हो तो परिणाम सटीक है। अन्यथा, यह अगले निचले या उच्च प्रतिनिधित्व योग्य मूल्य के कार्यान्वयन-परिभाषित विकल्प है। [नोट: परिशुद्धता का नुकसान तब होता है जब अभिन्न मूल्य को फ़्लोटिंग प्रकार के मान के रूप में बिल्कुल प्रदर्शित नहीं किया जा सकता है। ] यदि स्रोत का प्रकार bool है, तो मान false को शून्य में परिवर्तित किया गया है और मान true को एक में परिवर्तित किया गया है।

संदर्भ: What Every Computer Scientist Should Know About Floating-Point Arithmetic

अन्य अत्यधिक मूल्यवान तेजी float के विषय पर संदर्भ int को रूपांतरण:

एक अच्छा पढ़ा है!

+0

हां यह एक प्रदर्शन प्रभाव का तात्पर्य है, मैं ब्याज के अधिक संदर्भों के साथ प्रश्न संपादित कर रहा हूं –

+0

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

2

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

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

जब आप एक पूर्णांक मान को एक फ़्लोटिंग-पॉइंट प्रकार में परिवर्तित करते हैं, तो मूल मान बिल्कुल परिवर्तित होता है यदि इसे लक्ष्य प्रकार द्वारा बिल्कुल प्रदर्शित किया जा सकता है। अन्यथा, रूपांतरण प्रक्रिया द्वारा मूल्य बदल दिया जाएगा।

जब आप एक फ़्लोटिंग-पॉइंट मान को पूर्णांक प्रकार में परिवर्तित करते हैं, तो fractional भाग को त्याग दिया जाता है (यानी निकटतम मूल्य नहीं लिया जाता है, लेकिन संख्या शून्य की ओर गोल होती है)। यदि परिणाम लक्ष्य पूर्णांक प्रकार में फिट नहीं होता है, तो व्यवहार अपरिभाषित है।

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

4

आम तौर पर रन-टाइम रूपांतरण होते हैं, क्योंकि बिट प्रतिनिधित्व आमतौर पर संगत नहीं होते हैं (अपवाद के साथ कि द्विआधारी 0 आमतौर पर 0 और 0.0 दोनों होते हैं)। सी और सी ++ मानक केवल मूल्य के साथ सौदा करते हैं, प्रतिनिधित्व नहीं करते हैं, और आम तौर पर उचित व्यवहार निर्दिष्ट करते हैं। याद रखें कि एक बड़ा int मान आमतौर पर float में बिल्कुल सटीक नहीं होगा, और एक बड़े float मान को int द्वारा प्रदर्शित नहीं किया जा सकता है।

इसलिए:

सभी रूपांतरण, मूल्य से कर रहे हैं बिट पैटर्न नहीं। बिट पैटर्न के बारे में चिंता मत करो।

अंतहीनता के बारे में चिंता न करें, क्योंकि यह थोड़ा सा प्रतिनिधित्व है।

int से float कनवर्ट करना सटीकता खो सकता है यदि पूर्णांक मान पूर्ण मूल्य में बड़ा है; double के साथ यह कम होने की संभावना है, क्योंकि double अधिक सटीक है, और कई और सटीक संख्याओं का प्रतिनिधित्व कर सकता है। (विवरण इस बात पर निर्भर करता है कि सिस्टम वास्तव में किस प्रस्तुति का उपयोग कर रहा है।)

भाषा परिभाषाएं बिट पैटर्न के बारे में कुछ भी नहीं कहती हैं।

float से int में कनवर्ट करना भी मूल्यों का मामला है, बिट पैटर्न नहीं। एक सटीक फ़्लोटिंग-पॉइंट 2.0 एक अभिन्न 2 में परिवर्तित हो जाएगा क्योंकि इस तरह कार्यान्वयन स्थापित किया गया है, बिट पैटर्न के कारण नहीं।

+0

+1। आपको केवल याद रखने वाली एकमात्र चीज यह है कि गोल करने की बजाय int truncates पर तैरती है (.NET के विपरीत) - अन्यथा यह सीधा है। (यदि आप 'डबल' और 'लम्बे' तक चिपके रहते हैं तो खोए गए परिशुद्धता के मुद्दे को बहुत अधिक अनदेखा किया जा सकता है ...) – AAT

0

यदि आप मूल्य डालते हैं, तो यह परिवर्तित हो जाएगा (इसलिए एक फ्लोट -> int रूपांतरण 3.14 3 हो जाता है)।

लेकिन यदि आप पॉइंटर डालेंगे, तो आप वास्तव में अंतर्निहित बिट्स को 'दोबारा परिभाषित करेंगे'। तो यदि आप ऐसा कुछ करते हैं:

double d = 3.14; 
int x = *reinterpret_cast<int *>(&d); 

x में 'यादृच्छिक' मान होगा जो फ़्लोटिंग पॉइंट के प्रतिनिधित्व पर आधारित होगा।

0

एफपी को अभिन्न प्रकार में कनवर्ट करना नॉनट्रिविअल है और यहां तक ​​कि पूरी तरह परिभाषित नहीं है।

आमतौर पर आपका एफपीयू आईईईई प्रारूप से int में कनवर्ट करने के लिए हार्डवेयर निर्देश लागू करता है। वह निर्देश राउंडिंग को नियंत्रित करने वाले पैरामीटर (हार्डवेयर में कार्यान्वित) ले सकता है। आपका एबीआई शायद गोल-टू-नजदीकी-यहां तक ​​कि निर्दिष्ट करता है। यदि आप X86 + SSE पर हैं, तो यह "शायद बहुत धीमी नहीं है," लेकिन मुझे एक Google खोज के साथ संदर्भ नहीं मिल रहा है।

कुछ भी एफपी के साथ, कोने के मामले हैं। यह अच्छा होगा अगर अनंतता (TYPE)_MAX पर मैप की गई थी लेकिन यह आमतौर पर मामला नहीं है - int x = INFINITY; का परिणाम अपरिभाषित है।

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

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