2015-06-21 5 views
12

असल में, मैं float16 प्रकार को लागू करना चाहता हूं। लेकिन यह सवाल यह नहीं है कि इसे कैसे किया जाए, लेकिन इसके बजाय चीजों को कैसे सेट अप करें ताकि मेरा नया फ्लोट 16 प्रकार फ्लोट, डबल और सभी पूर्णांक प्रकारों के साथ उचित तरीके से व्यवहार कर सके।सी ++ 11 में, मैं एक अंकगणितीय प्रकार को कैसे कार्यान्वित कर सकता हूं जो बिल्टिन प्रकारों के पदानुक्रम में फिट बैठता है?

मुझे अपने float16 प्रकार के लिए समान रूप से फ़्लोट या डबल के रूप में परिवर्तित करने के लिए क्या चाहिए। उदाहरण के लिए, इसे इन दोनों प्रकारों में निहित रूप से डालना चाहिए। इसमें std :: common_type (http://en.cppreference.com/w/cpp/types/common_type) भी इसके लिए समान रूप से व्यवहार करना चाहिए क्योंकि यह std :: common_types अन्य फ्लोट प्रकारों के लिए व्यवहार करता है। इसका मतलब है कि std::common_type<my_float16, float>::type = float, std::common_type<my_float16, double>::type = double, और std::common_type<my_float16, T>::type = my_float16 जहां T कोई पूर्णांक प्रकार है।

इस काम को करने के लिए मुझे किस रचनाकार और कलाकार ऑपरेटरों को लिखने की आवश्यकता है? किसी भी सहायता की सराहना की जाएगी!

मेरा other recent question संबंधित हो सकता है।

संपादित करें: ठीक है, मैंने एंटोन की तरह एक न्यूनतम उदाहरण बनाया है। यह

struct float16 { 
    explicit operator int() { 
     return 0; 
    } 

    operator float() { 
     return 0.0f; 
    } 
}; 

यह फ्लोट और फ्लोट 16 के लिए सही सामान्य प्रकार है, लेकिन int और float16 के लिए सामान्य प्रकार अभी भी int है। मझे यह समझ में नहीं आता कि।

+2

अपने प्रश्न का उत्तर देने का प्रयास करने के बाद मुझे एक [GCC में अच्छी बग] मिली है (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66615) जो पूरे विचार को बहुत खतरनाक बना सकता है –

+0

मई मैं पूछता हूं कि किसी को कभी 16 बिट्स फ्लोट की आवश्यकता क्यों होगी? क्या यह सिर्फ एक अभ्यास है? – DarioP

+0

इसे आधा परिशुद्धता कहा जाता है, और ग्राफिक्स और अन्य चीजों में अनुप्रयोग हैं - https://en.wikipedia.org/wiki/Half-precision_floating-point_format देखें। मैं एक फ्लोट 128 प्रकार को भी कार्यान्वित करना चाहता हूं, जिस पर एक ही प्रश्न लागू होता है। – user2333829

उत्तर

0

मैं इस प्रश्न का अपना उत्तर प्रदान करने जा रहा हूं।

अब मैं 6502 से सहमत हूं, और मुझे नहीं लगता कि यह एक आसान तरीके से संभव है। ऐसा करने का एकमात्र तरीका यह था कि प्रकार के हर संभावित संयोजन के लिए ऑपरेटर ओवरलोड प्रदान करना था। यह टेम्पलेट्स (और बूस्टर ऑपरेटरों, http://www.boost.org/doc/libs/1_59_0/libs/utility/operators.htm के साथ थोड़ा अच्छे तरीके से किया जा सकता है, इसका एक अच्छा उदाहरण है), लेकिन यह अभी भी एक अच्छी मात्रा में काम और बॉयलरप्लेट कोड है।

4

मुझे नहीं लगता कि आप इसे बिल्कुल प्राप्त कर सकते हैं, क्योंकि सी ++ कोर भाषा मूल रूप से परिभाषित रूपांतरण (उदा। char से int) उपयोगकर्ता परिभाषित रूपांतरण से अलग है (भले ही वे निहित हैं)।

उदाहरण के लिए के बाद

struct float16 { float16(int) {} }; // cast int->float16 is implicit 

struct Foo { Foo(const double&){} }; // constructor accepts a double& 
struct Bar { Bar(const float16&){} }; // constructor accepts a float16& 

void foo(const Foo&) {} 
void bar(const Bar&) {} 

कॉल foo(3) वैध है क्योंकि पूर्णांक 3 एक double और foo को परोक्ष परिवर्तित किया जा सकता एक Foo उदाहरण है कि एक उपयोगकर्ता-निर्धारित रूपांतरण द्वारा एक double से परोक्ष निर्माण किया जा सकता स्वीकार करता है (Foo कन्स्ट्रक्टर जो explicit नहीं है)।

हालांकि bar(3)है मान्य नहीं है क्योंकि इस तरह के एक कॉल दो अंतर्निहित उपयोगकर्ता परिभाषित रूपांतरण (intfloat16 और → Barfloat16) और इसकी अनुमति नहीं है की आवश्यकता होगी नहीं

+0

धन्यवाद @ 6502। मुझे चिंता है कि आप सही हो सकते हैं, लेकिन मुझे यकीन नहीं है। – user2333829

+0

क्या आप मानक में किसी स्थान पर इंगित करने में सक्षम होंगे जो दिखाता है कि यह मामला है? यदि यह असंभव है, तो मैं स्पष्ट रूप से समझना चाहता हूं कि यह कहां किया गया है। – user2333829

+0

@ user2333829: संपादन देखें, मैंने एक उदाहरण जोड़ा है। ध्यान दें कि सी ++ के ओवरलोड रिज़ॉल्यूशन के लिए सटीक नियम हैं (कम से कम मेरे लिए) उन्हें जटिल सीखने के लिए बहुत जटिल हैं और मैं अधिक जटिल मामलों को बाहर नहीं रखता हूं। – 6502

2

यदि आप इसे एक संरचना/वर्ग प्रकार के रूप में कार्यान्वित करते हैं, तो सभी प्रासंगिक ऑपरेटरों और रचनाकारों के अधिभार प्रदान करें। यदि किसी वर्ग की आवश्यकता होती है तो इसके लिए दिशानिर्देश देखें, यदि यह अन्य प्रकार से रूपांतरणों का समर्थन करता है।

यदि आप चाहते हैं कि आपकी कक्षा std::common_type और std::numeric_limits जैसे मानक टेम्पलेट्स के साथ अच्छी तरह से खेलें, तो आपको उन टेम्पलेट्स के उचित विशेषज्ञता प्रदान करने की आवश्यकता होगी। ऐसी विशेषज्ञता की आवश्यकताओं के विवरण के लिए वास्तविक मानकों को पढ़ना शायद सबसे अच्छा है, लेकिन शायद कुछ ट्यूटोरियल सामग्री है (मैंने std::numeric_limits विशेषज्ञता के लिए अच्छी प्रारंभिक सामग्री देखी है, लेकिन std::common_type के लिए नहीं)।

अंतर्निहित मानक प्रकारों (int, float, आदि) के साथ आपका प्रकार किस प्रकार फिट बैठता है, इस पर कुछ सीमाएं हमेशा रहेंगी जब तक कि आप कंपाइलर-विशिष्ट प्रकार का उपयोग न करें।

+0

धन्यवाद, पीटर। मेरा सवाल वास्तव में वास्तव में है कि इस काम को करने के लिए रचनाकारों और ऑपरेटरों को लागू करने की आवश्यकता है। मेरे पास एक वर्ग है जिसमें से कई लागू किए गए हैं, लेकिन मुझे अभी भी सटीक व्यवहार नहीं मिल रहा है (जो मैंने ऊपर निर्दिष्ट किया है)। Std :: common_type को अधिभारित करने के लिए, यह मेरे लिए आखिरी उपाय है - मैं चीजों को काम करना चाहता हूं ताकि std :: common_type स्वाभाविक रूप से टर्नरी ऑपरेटर के रिटर्न प्रकार का उपयोग करके काम करता है। – user2333829

+0

मेरे सिर के ऊपर, न्यूनतम सभी संख्यात्मक ऑपरेटरों ('ऑपरेटर +()', आदि), सभी 'op =' ऑपरेटरों ('ऑपरेटर + =()', आदि), रूपांतरण कन्स्ट्रक्टर और संबंधित 'ऑपरेटर =() '[ सभी मूलभूत प्रकारों के लिए अधिभारित], सभी रूपांतरण कन्स्ट्रक्टर ('ऑपरेटर फ्लोट()', आदि)। सी ++ 11 के लिए, अपनी कक्षा के आंतरिक के आधार पर, कन्स्ट्रक्टर को सलाह दी जाती है। Bitwise ऑपरेटरों की आपूर्ति मत करो। आपूर्ति धारा सम्मिलन और निष्कर्षण ऑपरेटर। ऑपरेटर जिन्हें जंजीर (जैसे '=' और '+ =') संदर्भित किया जा सकता है, अन्य मूल्य से वापस आते हैं। – Peter

+0

हे पीटर। Std :: common_type काम करने के लिए, मुझे लगता है कि केवल एक को रचनाकारों को लागू करने की आवश्यकता है (चालक कन्स्ट्रक्टर के बारे में भी निश्चित नहीं है) और कलाकारों को कास्ट करें। बाकी इन विशेष परिचालनों के लिए है, जो निश्चित रूप से उपयोगी हैं लेकिन std :: common_type जैसी चीजों को प्रभावित नहीं करते हैं। – user2333829

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

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