2016-12-28 6 views
8

सी ++ 14 मूल्य के लिए 0b उपसर्ग टाइप करके बाइनरी शाब्दिक उपयोग करने की क्षमता जोड़ता है:क्या सी ++ मानक में std :: bin जोड़ने का प्रस्ताव रहा है?

int v = 0b1111; // 15 in decimal 

लेकिन वहाँ std::hex या std::oct तरह धाराओं के लिए कोई std::bin जोड़तोड़ है। तो मुझे उदाहरण का उपयोग करने की ज़रूरत है मुद्रण उद्देश्य के लिए std::bitset:

std::cout << std::bitset<4>(v) << "\n"; 

यह प्रस्ताव या विचार किया गया है? यदि हां, तो विचार की स्थिति क्या है?

+4

शायद सिर्फ भुला दिया गया/कोई भी समय लिख सकते हैं और एक कागज की रक्षा के लिए ले लिया। – MikeMB

+0

बाइनरी में प्रिंटिंग संख्या का अक्सर उपयोग नहीं किया जाता है। – alain

+0

@alain octal के लिए समान ... मुझे लगता है कि – alexolut

उत्तर

5

जहां तक ​​मुझे पता है कि बाइनरी स्वरूपण और/या एक मैनिपुलेटर std::bin जोड़ने के लिए स्वरूपण ध्वज जोड़ने के लिए कोई प्रस्ताव प्रस्तुत नहीं किया गया था। आप http://www.open-std.org/jtc1/sc22/wg21/docs/papers/ पर प्रस्तावों की जांच कर सकते हैं। मुझे पूरा यकीन है कि द्विआधारी अक्षर जोड़ने का प्रस्ताव इस सुविधा को नहीं जोड़ा गया है (एक त्वरित खोज N3472 से पता चला लेकिन मुझे यकीन नहीं है कि यह कागज का नवीनतम संस्करण है)।

तकनीकी दृष्टि से यह जोड़ना पूरी तरह से आसान नहीं हो सकता है! विभिन्न झंडे आमतौर पर स्ट्रीम कक्षा में केवल एक शब्द में संग्रहीत होते हैं और सभी बिट्स का उपयोग करने के कई कारण हैं। मौजूदा तीन सेटिंग्स (std::ios_base::oct, std::ios_base::dec, std::ios_base::hex) को केवल 2 बिट्स में अच्छी तरह से संग्रहीत किया जा सकता है। बेशक, तीन मान एक मूल्य खुला छोड़ देंगे, सिवाय इसके कि यह मान आम तौर पर डिफ़ॉल्ट सेटिंग के लिए लिया जाता है, यानी, पढ़ने के दौरान आधार को ठीक नहीं किया जाता है। नतीजतन, धारा वर्गों के लेआउट को बदलने या प्रसंस्करण कम कुशल बनाने के लिए आवश्यक हो सकता है (उदाहरण के लिए, किसी भी तरह से iword() का उपयोग बाइनरी स्वरूपण की अतिरिक्त संभावना को संग्रहीत करने के लिए)। मैंने विश्लेषण नहीं किया है कि किसी भी कार्यान्वयन के साथ कोई वास्तविक समस्या है (मुझे पता है कि मेरे कार्यान्वयन के लिए कोई नहीं है, लेकिन अगर मैं सही ढंग से याद करता हूं तो मैंने एक शब्द में सभी बिट्स का उपयोग किया था)।

यदि आप बाइनरी स्वरूपण का समर्थन करना चाहते हैं तो यह कस्टम std::num_put<char> पहलू के माध्यम से जोड़ने के लिए अपेक्षाकृत आसान है। नीचे एक साधारण उदाहरण है। यह स्वरूपण विकल्प जो गद्दी या अंकों विभाजक की तरह वांछनीय हो सकता है में से कुछ के साथ सौदा नहीं करता है:

#include <iostream> 
#include <limits> 
#include <locale> 

class binary_num_put 
    : public std::num_put<char> { 
    template <typename T> 
    iter_type common_put(iter_type out, std::ios_base& str, char_type fill, 
         T original, unsigned long long v) const { 
     if (str.flags() & std::ios_base::basefield) { 
      return this->std::num_put<char>::do_put(out, str, fill, original); 
     } 
     if (str.flags() & std::ios_base::showbase) { 
      *out++ = '0'; 
      *out++ = str.flags() & std::ios_base::uppercase? 'B': 'b'; 
     } 
     unsigned long long mask(1ull << (std::numeric_limits<unsigned long long>::digits - 1)); 
     while (mask && !(mask & v)) { 
      mask >>= 1; 
     } 
     if (mask) { 
      for (; mask; mask >>= 1) { 
       *out++ = v & mask? '1': '0'; 
      } 
     } 
     else { 
      *out++ = '0'; 
     } 
     return out; 
    } 
    iter_type do_put(iter_type out, std::ios_base& str, char_type fill, long v) const { 
     return common_put(out, str, fill, v, static_cast<unsigned long>(v)); 
    } 
    iter_type do_put(iter_type out, std::ios_base& str, char_type fill, long long v) const { 
     return common_put(out, str, fill, v, static_cast<unsigned long long>(v)); 
    } 
    iter_type do_put(iter_type out, std::ios_base& str, char_type fill, unsigned long v) const { 
     return common_put(out, str, fill, v, v); 
    } 
    iter_type do_put(iter_type out, std::ios_base& str, char_type fill, unsigned long long v) const { 
     return common_put(out, str, fill, v, v); 
    } 
}; 

std::ostream& bin(std::ostream& out) { 
    auto const& facet = std::use_facet<std::num_get<char>>(out.getloc()); 
    if (!dynamic_cast<binary_num_put const*>(&facet)) { 
     std::locale loc(std::locale(), new binary_num_put); 
     out.imbue(loc); 
    } 
    out.setf(std::ios_base::fmtflags(), std::ios_base::basefield); 
    return out; 
} 

int main() 
{ 
    std::cout << std::showbase << bin << 12345 << " " 
       << std::dec << 12345 << "\n"; 
} 
+0

मैंने जिन सभी कार्यान्वयनों की जांच की, डीसी, ऑक्टेट और हेक्स अलग-अलग बिट्स हैं। और कम से कम libstdC++ (और 32+ बिट प्लेटफ़ॉर्म पर libC++) में बहुत से अतिरिक्त बिट्स हैं, जो दूसरों के बारे में निश्चित नहीं हैं। –

+0

@MarcGlisse: मुझे पता है कि [मेरा कार्यान्वयन] (http://www.dietmar-kuehl.de/cxxrt/) * अलग * बिट्स का उपयोग नहीं करता है। माना जाता है कि यह आधार स्टोर करता है, यानी, 'std :: bin' मैनिपुलेटर जोड़ने के लिए यह छोटा होगा। मेरा कार्यान्वयन एक ही शब्द में कई स्थितियों को फोल्ड करता है ताकि एकाधिक शाखाओं और एक मेमोरी एक्सेस के साथ कई अलग-अलग स्थितियों की जांच की जा सके (और ऐसा लगता है कि वास्तव में 32 बिट शब्दों के लिए वास्तव में एक अतिरिक्त बिट था)। –

+0

मानक कहता है कि ['fmtflags' एक बिटमास्क प्रकार और' dec', 'oct' और' हेक्स' (दूसरों के बीच) इसके तत्व हैं] (https://timsong-cpp.github.io/cppwp/ios: : fmtflags # 1), जिसका अर्थ है कि [उन्हें प्रभावी बिट्स का प्रभावी ढंग से प्रतिनिधित्व करना चाहिए] (https://timsong-cpp.github.io/cppwp/bitmask.types#3) (क्योंकि उनमें से किसी भी दो को 'बिटैंड' करना चाहिए शून्य)।बेशक, एक कार्यान्वयन एक अलग आंतरिक प्रतिनिधित्व का उपयोग करना चुन सकता है, लेकिन इसके लिए दोनों तरीकों से अनुवाद प्रदान करने के लिए अतिरिक्त कार्य की आवश्यकता होती है। –

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