यह (कम से कम आईईईई 754 float
और double
मूल्यों के लिए) (छद्म कोड) के माध्यम से सबसे बड़ी फ्लोटिंग प्वाइंट मूल्य की गणना करने के लिए संभव है:
~(-1.0) | 0.5
इससे पहले कि हम हमारे बिट twiddling कर सकते हैं, हम फ्लोटिंग-पॉइंट मानों को पूर्णांक में परिवर्तित करना होगा और फिर फिर से वापस करना होगा। यह निम्न तरीके से किया जा सकता है:
uint64_t m_one, half;
double max;
*(double *)(void *)&m_one = -1.0;
*(double *)(void *)&half = 0.5;
*(uint64_t *)(void *)&max = ~m_one | half;
तो यह कैसे काम करता है? इसके लिए, हमें यह जानना होगा कि फ़्लोटिंग-पॉइंट मान कैसे एन्कोड किए जाएंगे।
उच्चतम बिट साइन को एन्कोड करता है, अगले k
बिट्स एक्सपोनेंट को एन्कोड करते हैं और निम्नतम बिट्स आंशिक भाग को पकड़ेंगे। 2
की शक्तियों के लिए, आंशिक भाग 0
है।
एक्सपोनेंट 2**(k-1) - 1
के पूर्वाग्रह (ऑफ़सेट) के साथ संग्रहीत किया जाएगा, जिसका अर्थ है 0
का एक एक्सपोनेंट सभी के साथ एक पैटर्न के अनुरूप है लेकिन उच्चतम बिट सेट के साथ है।
वहाँ विशेष अर्थ के साथ दो प्रतिपादक बिट पैटर्न हैं:
- अगर कोई थोड़ा सेट किया गया है, मूल्य
0
हो सकता है अगर आंशिक हिस्सा शून्य है; अन्यथा, मूल्य एक सामान्य से कम
- सभी बिट्स सेट कर रहे हैं, मूल्य या तो
infinity
या NaN
इसका मतलब यह है सबसे बड़ी नियमित प्रतिपादक सबसे कम है, जो से मेल खाती है के अलावा सभी बिट्स की स्थापना के माध्यम से इनकोडिंग हो जाएगा है यदि आप पूर्वाग्रह को घटाते हैं तो 2**k - 2
या 2**(k-1) - 1
का मान।
double
के लिए मूल्यों, k = 11
, यानी उच्चतम प्रतिपादक 1023
हो जाएगा, तो सबसे बड़ी चल बिन्दु मूल्य आदेश 2**1023
है जो 1E+308
के बारे में है।
सबसे ज्यादा मूल्य
- संकेत बिट
0
- सब करने के लिए सेट लेकिन सबसे कम प्रतिपादक बिट
1
- करने के लिए सभी आंशिक बिट्स अब
1
करने के लिए सेट सेट करना होगा, यह समझना संभव है कि हमारे जादू संख्या कैसे काम करती हैं:
-1.0
इसके संकेत बिट सेट है, प्रतिपादक पूर्वाग्रह है - यानी सभी बिट्स लेकिन उच्चतम एक मौजूद हैं - और आंशिक भाग 0
~(-1.0)
केवल उच्चतम प्रतिपादक सा है और सभी आंशिक बिट्स सेट किया गया है
0.5
में 0
का एक साइन बिट और fractional हिस्सा है; प्रतिपादक पूर्वाग्रह शून्य से 1
हो जाएगा, यानी सभी लेकिन उच्चतम और निम्नतम प्रतिपादक बिट्स वर्तमान
जब हम तार्किक के माध्यम से इन दो मानों गठबंधन होगा या, हम सा पैटर्न हम चाहते थे मिल जाएगा।
गणना 86 80-बिट बढ़ाया परिशुद्धता मूल्यों (उर्फ long double
) के साथ के लिए काम करता है, लेकिन थोड़ा-twiddling बाइट के लिहाज से किया जाना चाहिए के रूप में कोई पूर्णांक प्रकार इतना बड़ा 32- पर मान धारण करने के लिए बिट हार्डवेयर।
पूर्वाग्रह वास्तव में 2**(k-1) - 1
होने की आवश्यकता नहीं है - यह एक मनमाना पूर्वाग्रह के लिए काम करेगा जब तक कि यह विषम है। पूर्वाग्रह अजीब होना चाहिए क्योंकि अन्यथा 1.0
और 0.5
के एक्सपोनेंट के लिए बिट-पैटर्न सबसे कम बिट की तुलना में अन्य स्थानों में भिन्न होंगे।
तो आधार b
(उर्फ मूलांक) फ्लोटिंग प्वाइंट प्रकार के 2
नहीं है, आप b**(-1)
बजाय 0.5 = 2**(-1)
उपयोग करना होगा।
यदि सबसे बड़ा एक्सपोनेंट मान reserverd नहीं है, तो 0.5
के बजाय 1.0
का उपयोग करें। यह आधार या पूर्वाग्रह के बावजूद काम करेगा (जिसका अर्थ है कि यह अब अजीब मानों तक सीमित नहीं है)। 1.0
का उपयोग करने में अंतर यह है कि सबसे कम एक्सपोनेंट बिट साफ़ नहीं किया जाएगा।
संक्षेप में:
~(-1.0) | 0.5
जब तक मूलांक 2
है काम करता है, पूर्वाग्रह विषम है और उच्चतम प्रतिपादक आरक्षित है।
~(-1.0) | 1.0
किसी भी रेडिक्स या पूर्वाग्रह के लिए काम करता है जब तक कि उच्चतम एक्सपोनेंट आरक्षित न हो।
नहीं। वहाँ एक पोर्टेबल पर्वतमाला की गणना करने के लिए रास्ता नहीं है:
आपको लगता है कि फ्लोट.h से बचने का मतलब क्यों है? अच्छा मुझे लगता है कि यह चाहता है कि आप कुछ फ़ंक्शन जैसे ldexp, FLT_RADIX (या जिसे भी कहा जाता है) और सामग्री –
अच्छी तरह से उपयोग करें, क्योंकि float.h में पहले से ही न्यूनतम/अधिकतम मान उपलब्ध हैं जो इस मामले में धोखाधड़ी की तरह लगेंगे। लेकिन हाँ, float.h में परिभाषित कुछ अन्य स्थिरांक हैं जो संभवतः वास्तविक श्रेणियों को निर्धारित करने के लिए उपयोग किए जा सकते हैं। – Ree