हाल ही में, मैं पोस्ट पढ़ रहा था:समझौता: डबल या कुछ भी नहीं
int main()
{
double x = 1e8;
while(x > 0)
{
--x;
}
}
मान लें कि इस कोड को चलाता है: Double or Nothing from GOTW by Herb Sutter मैं एक छोटे से निम्नलिखित कार्यक्रम के विवरण के साथ उलझन में हूँ कुछ मशीन में 1 सेकंड। मैं इस बिंदु से सहमत हूं कि इस तरह का कोड मूर्खतापूर्ण है।
हालांकि, इस मुद्दे के बारे में विवरण के अनुसार अगर हम x
float
से double
को बदलने के लिए, तो कुछ compilers पर, यह कंप्यूटर हमेशा के लिए चलते रहेंगे। स्पष्टीकरण मानक से निम्नलिखित उद्धरण पर आधारित है।
खंड सी ++ मानक के 3.9.1/8 से हवाला देते हुए:
रहे हैं तीन चल बिन्दु प्रकार: नाव, डबल, और लंबे समय तक डबल। प्रकार डबल कम से कम उतना सटीक प्रदान करता है जितना कि फ्लोट के रूप में, और लंबे समय तक डबल डबल के रूप में कम से कम सटीकता प्रदान करता है। प्रकार फ्लोट के मानों का सेट डबल प्रकार के मानों के सेट का एक सबसेट है; प्रकार डबल के मानों का सेट लंबे प्रकार के मानों के सेट का एक सबसेट है।
कोड के लिए सवाल यह है:
आप कब तक यदि आप "फ्लोट" बदल "डबल" यह लेने के लिए उम्मीद करेंगे? क्यूं कर?
यहाँ विवरण दिया है:
यह शायद या तो के बारे में 1 सेकंड ले जाएगा (एक विशेष कार्यान्वयन तैरता पर कुछ हद तक तेजी के रूप में तेजी से, या डबल्स की तुलना में कुछ धीमी हो सकती है,), या हमेशा के लिए , फ्लोट के आधार पर 0 से 1e8 समेत सभी पूर्णांक मानों का प्रतिनिधित्व कर सकते हैं या नहीं।
मानक से उपरोक्त उद्धरण का अर्थ है कि ऐसे मूल्य हो सकते हैं जिन्हें डबल द्वारा दर्शाया जा सकता है लेकिन इसे एक फ्लोट द्वारा प्रदर्शित नहीं किया जा सकता है। विशेष रूप से, कुछ लोकप्रिय प्लेटफार्मों और कंपाइलरों पर, डबल [0,1e8] में सभी पूर्णांक मानों का बिल्कुल प्रतिनिधित्व कर सकते हैं लेकिन फ्लोट नहीं कर सकता है।
क्या होगा यदि फ्लोट 0 से 1e8 तक सभी पूर्णांक मानों का बिल्कुल प्रतिनिधित्व नहीं कर सकता है? फिर संशोधित कार्यक्रम उल्टी गिनती शुरू कर देंगे, लेकिन अंत में एक मूल्य के एन जो नहीं दर्शाया जा सकता तक पहुंच जाएगा और जिसके लिए एन 1 == N (अपर्याप्त फ्लोटिंग प्वाइंट परिशुद्धता के कारण) ... और
मेरा सवाल है:
यदि फ्लोट 1e8
का प्रतिनिधित्व करने में भी सक्षम नहीं है, तो हमें float x = 1e8
प्रारंभ करने पर पहले से ही अतिप्रवाह होना चाहिए; तो हम कंप्यूटर को हमेशा के लिए कैसे चलेंगे?
मैं यहाँ एक सरल उदाहरण की कोशिश की है (हालांकि double
नहीं लेकिन int
)
#include <iostream>
int main()
{
int a = 4444444444444444444;
std::cout << "a " << a << std::endl;
return 0;
}
It outputs: a -1357789412
इसका मतलब यह है कि अगर संकलक int
प्रकार के साथ दी गई संख्या का प्रतिनिधित्व करने में सक्षम नहीं है, यह अतिप्रवाह का परिणाम देगा।
तो क्या मैंने गलत पढ़ा? मुझे क्या याद आया? double
से float
अपरिभाषित व्यवहार बदल रहा है?
धन्यवाद!
अच्छी जानकारी के लिए धन्यवाद, लेकिन मेरा सवाल यह है कि अगर शुरुआती समय में ओवरफ्लो हो तो क्यों लूप भी शुरू होगा? – taocp
@taocp आपके पास प्रारंभिकरण पर ओवरफ़्लो नहीं है। फ़्लोटिंग पॉइंट प्रारूप लगातार * सटीक * होते हैं जब तक आप उच्च मान पर नहीं जाते हैं जब तक कि आप + 1. # INF तक नहीं पहुंच जाते। अनंत पर संचालन, और # एनएएन कानूनी हैं, अपरिभाषित नहीं हैं। हालांकि उनके पास अप्रत्याशित परिणाम हो सकते हैं। [आईईईई -754 मानक] (https://en.wikipedia.org/wiki/IEEE_floating_point) पर एक नज़र डालें –
@indeterminatelyately आह, इसके लिए बहुत बहुत धन्यवाद। – taocp