2015-12-15 16 views
33

T के लिए std::is_floating_point<T>::valuetrue है, क्या सी ++ मानक T को लागू करने के तरीके पर कुछ भी निर्दिष्ट करता है?क्या सी ++ मानक फ़्लोटिंग पॉइंट नंबरों के प्रतिनिधित्व पर कुछ भी निर्दिष्ट करता है?

उदाहरण के लिए, T पर भी एक संकेत/मंटिसा/एक्सपोनेंट प्रतिनिधित्व का पालन करना है? या यह पूरी तरह से मनमाना हो सकता है?

उत्तर

37

N3337 से:

[basic.fundamental/8]: वहाँ तीन चल बिन्दु प्रकार हैं: नाव, डबल, और लंबे समय तक डबल। प्रकार डबल कम से कम फ्लोट के रूप में बहुत सटीक प्रदान करता है, और लंबे समय तक डबल डबल के रूप में कम से कम सटीकता प्रदान करता है। प्रकार फ्लोट के मानों का सेट डबल प्रकार के मानों के सेट का एक सबसेट है; टाइप डबल के मान का सेट लंबे प्रकार के मानों के सेट का सेट सबसेट है। का मूल्य प्रतिनिधित्व फ़्लोटिंग-पॉइंट प्रकार कार्यान्वयन-परिभाषित है। इंटीग्रल और फ़्लोटिंग प्रकारों को सामूहिक रूप से अंकगणित प्रकार कहा जाता है। मानक टेम्पलेट std :: numeric_limits (18.3) की विशेषज्ञता अधिकतम और कार्यान्वयन के लिए प्रत्येक अंकगणितीय प्रकार के न्यूनतम मान निर्दिष्ट करेगी।

आप अपने कार्यान्वयन का उपयोग करता है आईईईई-754 की जांच करना चाहते हैं, तो आप std::numeric_limits::is_iec559 उपयोग कर सकते हैं:

static_assert(std::numeric_limits<double>::is_iec559, 
       "This code requires IEEE-754 doubles"); 

इस क्षेत्र में अन्य सहायक लक्षण के एक नंबर, जैसे has_infinity, quiet_NaN और more रहे हैं ।

+1

आपका उद्धरण वास्तव में प्रश्न का उत्तर नहीं देता है। सवाल पूछता है कि क्या फ्लोटिंग पॉइंट प्रारूपों पर प्रतिबंध हैं। आपके उत्तर से पता चलता है कि फ़्लोटिंग पॉइंट प्रारूपों को कार्यान्वयनकर्ता द्वारा दस्तावेज किया जाना चाहिए। यह संबंधित है लेकिन वास्तव में एक ही बात नहीं है। – hvd

+6

@ एचवीडी: वह (कार्यान्वयनकर्ता दस्तावेज प्रदान करना होगा) गणित पुस्तकालय को लागू करने वाली आवश्यक श्रेणियों और संचालन के अलावा, केवल एक ही प्रतिबंध है। –

+0

@hvd मुझे यकीन नहीं है कि मैं समझता हूं। उत्तर में एक आसान "यह एकमात्र प्रतिबंध" आपके लिए पर्याप्त होगा? – TartanLlama

3

std::is_floating_point का विचार विभिन्न मूल कार्यों के उपयोगकर्ता को बेहतर ढंग से कोड बनाना है। तकनीकी रूप से आप को std::is_floating_point के रूप में अनिर्धारित व्यवहार के बिना निर्दिष्ट कर सकते हैं। लेकिन कहें कि आपके पास कुछ टेम्पलेट लाइब्रेरी है जिसे बार-बार T n से विभाजित करना है। लाइब्रेरी को चीजों को गति देने के लिए T ni = 1/n बनाता है और द्वारा गुणा करके n द्वारा विभाजन को प्रतिस्थापित करता है। यह फ़्लोटिंग पॉइंट नंबरों के लिए बहुत अच्छा काम करता है, लेकिन पूर्णांक के लिए विफल रहता है। इसलिए std::is_floating_point<T>::value == true यदि पुस्तकालय सही ढंग से ऑप्टिमाइज़ेशन करता है। यदि आप कोड झूठ बोलते हैं तो शायद मानक के दृष्टिकोण से अभी भी काम करता है, लेकिन एक तार्किक दृष्टिकोण से गलत है। तो यदि आप एक वर्ग लिखते हैं जो एक बड़े float की तरह व्यवहार करता है तो इसे std::is_floating_point के रूप में चिह्नित करें, अन्यथा नहीं। यह आपको इष्टतम और सही कोड दोनों प्राप्त करना चाहिए।

7

कोई विशेष कार्यान्वयन आवश्यक नहीं है। सी ++ मानक इसके बारे में बिल्कुल बात नहीं करता है। सी मानक कुछ आधार b में एक संकेत, एक्सपोनेंट, महत्व के साथ, फ्लोटिंग पॉइंट नंबरों के लिए मानी जाने वाली वैचारिक मॉडल के बारे में काफी विस्तार से जाता है, और इसी तरह। हालाँकि इस बात पर विशेष रूप से कहा गया है कि यह विशुद्ध रूप से वर्णनात्मक कार्यान्वयन पर एक आवश्यकता नहीं है, (सी 11, फुटनोट 21):

फ्लोटिंग प्वाइंट मॉडल प्रत्येक फ्लोटिंग प्वाइंट विशेषता और का विवरण स्पष्ट करने का इरादा है कार्यान्वयन के फ़्लोटिंग-पॉइंट अंकगणित को समान होने की आवश्यकता नहीं है।

जिसके अनुसार, हालांकि विवरण भिन्न हो सकते हैं, कम से कम बेतकल्लुफ़ मुझे लगता है कि (उदाहरण के लिए) का निर्माण double के अनुरूप क्रियान्वयन कि बारीकी से हमेशा की तरह मॉडल के साथ काफी के अनुरूप नहीं थे (यानी, एक महत्व और एक्सपोनेंट) मुश्किल होगा (या प्रतिस्पर्धी प्रदर्शन के साथ कम से कम मुश्किल करना होगा)। यद्यपि यह अन्य तरीकों से भिन्न होना मुश्किल नहीं होगा, जैसे आदेश को पुन: व्यवस्थित करना, या एक अलग आधार का उपयोग करना।

std::numeric_limits<T>::digits (और std::numeric_limits<T>::digits10) की परिभाषा स्पष्ट रूप से सीधे बताती है कि एक फ़्लोटिंग पॉइंट प्रकार के रूप में सूचीबद्ध क्या होना चाहिए (कम से कम लगभग) परिमाण की एक विस्तृत श्रृंखला में सभी संख्याओं के लिए समान सटीकता को बनाए रखना चाहिए। इसे पूरा करने का सबसे स्पष्ट तरीका यह है कि कुछ महत्वपूर्ण बिट्स/अंकों को महत्व के लिए समर्पित किया गया है, और कुछ अन्य (अलग) एक एक्सपोनेंट को समर्पित बिट्स का सेट है।

+1

मुझे लगता है कि 'numeric_limits :: अंक' और 'अंक 10' की परिभाषाएं वहां कहीं से भी महत्वपूर्ण होने से दूर रहना मुश्किल हो जाती हैं (यह कैसे काम करता है इसका थोड़ा सा प्रतिनिधित्व एक और मामला है)। तो कम से कम आप एक निश्चित चौड़ाई प्रकार को 'डबल' और अनुरूप के रूप में नहीं जोड़ सकते हैं। मुझे लगता है कि आप करते हैं, यह * फ़्लोटिंग * बिंदु होने के लिए बाध्य है। एक अलग आधार का उपयोग स्पष्ट रूप से 'radix' द्वारा कवर किया गया है :-) –

+0

@SteveJessop: हाँ, यह मेरी सोच भी काफी थी। –

+0

@SteveJessop 'numeric_limits' की लगभग हर संपत्ति के लिए कॉपी-पेस्टिंग 'int' से आपको वास्तव में क्या रोकता है? – Yakk

10

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

मुझे नहीं पता कि सी ++ के लिए समकक्ष अनुबंध है या नहीं। यह N3337 में प्रकट नहीं होता है, लेकिन इसका मतलब यह हो सकता है कि यह अलग से वितरित किया गया है। std::numeric_limits<floating-type>::is_iec559 का अस्तित्व इंगित करता है कि सी ++ कमेटी कम से कम इस बारे में सोचा था, लेकिन शायद सी समिति के रूप में ज्यादा विस्तार से नहीं। (यह हमेशा एक शर्मिंदा शर्म की बात है कि सी ++ मानक सी मानक के संपादन के सेट के रूप में व्यक्त नहीं किया जाता है।)

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