दिलचस्प पोस्ट
अस्थायी NSManagedObject उदाहरणों के साथ सौदा कैसे करें? क्या सी में एक मानक कार्य है जो एक सरणी की लंबाई वापस करेगा? पीआईपी स्थापित करें lxml त्रुटि PHP से एक पायथन स्क्रिप्ट चलाना क्या मैं दूसरे वर्ग में किसी गतिविधि का उद्देश्य बना सकता हूं? क्रॉस प्लेटफॉर्म मोबाइल एप्लिकेशन का विकास एक SqlDataReader वस्तु में स्तंभ नाम की जांच करें पूर्वता के साथ समीकरण (अभिव्यक्ति) पार्सर? वैकल्पिक बाइंडिंग के माध्यम से स्विफ्ट में सुरक्षित (बाउंड-चेक) सरणी लुकअप? एंड्रॉइड: रिवर्स जीओकोडिंग – फिक्स्ड लॉकेशन स्प्रिंग एमवीसी (@ रेस्पॉन्सबॉडी) में प्रतिक्रिया सामग्री प्रकार किसने सेट करता है डेटा के साथ एक्सेल में पंक्तियों की संख्या कैसे गिनेंगी? मैं JSON संरचना पर पुनरावृत्त कैसे करूं? कैसे जावास्क्रिप्ट के साथ एक क्लिक अनुकरण? एंड्रॉइड: मैं संपादन टेक्स्ट इनपुट को कैसे सत्यापित कर सकता हूं?

क्या संकलित समय पर पूर्णांक प्रकार की चौड़ाई की गणना करने का कोई तरीका है?

char / बाइट की इकाइयों में एक पूर्णांक प्रकार (या किसी भी प्रकार) का आकार आसानी sizeof(type) रूप में गणना की जाती है। एक सामान्य मुहावरे को CHAR_BIT द्वारा टाइप किए गए बिट्स की संख्या को खोजने के लिए गुणा करना है, लेकिन पैडिंग बिट्स के कार्यान्वयन पर यह मूल्य बिट्स की चौड़ाई के बराबर नहीं होगा। इससे भी बदतर, कोड की तरह:

 x>>CHAR_BIT*sizeof(type)-1 

वास्तव में अपरिभाषित व्यवहार हो सकता है यदि CHAR_BIT*sizeof(type) की वास्तविक चौड़ाई से अधिक है

सादगी के लिए, मान लें कि हमारे प्रकार अहस्ताक्षरित हैं। फिर type की चौड़ाई ceil(log2((type)-1) । क्या इस मान को स्थिर अभिव्यक्ति के रूप में गणना करने का कोई तरीका है?

वेब के समाधान से एकत्रित समाधान "क्या संकलित समय पर पूर्णांक प्रकार की चौड़ाई की गणना करने का कोई तरीका है?"

एक फ़ंक्शन जैसी मैक्रो है जो कि **** मान बिट्स को पूर्णांक प्रकार के **** निर्धारित कर सकता है, लेकिन केवल अगर आप पहले से ही उस प्रकार का अधिकतम मान जानते हैं चाहे आप एक कंपाइल-टाइम स्थिर हो जाएंगे या नहीं, आपके कंपाइलर पर निर्भर करता है, लेकिन मुझे लगता है कि ज्यादातर मामलों में इसका जवाब हां है।

हॉलवार्ड बी। फ़ुरुसेथ को अपने IMAX_BITS () फ़ंक्शन जैसी मैक्रो के लिए श्रेय, जो उन्होंने comp.lang.c पर एक प्रश्न के जवाब में पोस्ट किया

 /* Number of bits in inttype_MAX, or in any (1<<b)-1 where 0 <= b < 3E+10 */ #define IMAX_BITS(m) ((m) /((m)%0x3fffffffL+1) /0x3fffffffL %0x3fffffffL *30 \ + (m)%0x3fffffffL /((m)%31+1)/31%31*5 + 4-12/((m)%31+3)) 

IMAX_BITS (INT_MAX) एक पूर्णांक में बिट्स की संख्या की गणना करता है, और IMAX_BITS ((अहस्ताक्षरित नहीं) -1) एक अहस्ताक्षरित प्रकार में बिट्स की संख्या की गणना करता है। जब तक कोई 4-गीगाबाइट पूर्णांक लागू करता है, वैसे भी 🙂

और इस वैकल्पिक संस्करण के लिए एरिक सोस्मन को क्रेडिट करना चाहिए जो 2040 से कम बिट्स के साथ काम करना चाहिए:
(संपादित करें 1/3/2011 11:30 पूर्वाह्न ईएसटी: यह पता चला है कि इस संस्करण को हॉलवर्ड बी। फुरुसथ द्वारा भी लिखा गया था)

 /* Number of bits in inttype_MAX, or in any (1<<k)-1 where 0 <= k < 2040 */ #define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12)) 

याद रखें कि हालांकि एक अहस्ताक्षरित पूर्णांक प्रकार की चौड़ाई मूल्य बिट की मात्रा के बराबर है, एक हस्ताक्षरित पूर्णांक प्रकार की चौड़ाई एक अधिक है (§6.2.6.2 / 6)। यह आपके विशेष प्रश्न के मुताबिक मेरी मूल टिप्पणी के रूप में महत्वपूर्ण है, मैंने गलत तरीके से कहा था कि IMAX_BITS () मैक्रो चौड़ाई की गणना करता है, जब यह वास्तव में मान बिट्स की गणना करता है उसके लिए माफ़ करना!

इसलिए उदाहरण के लिए IMAX_BITS(INT64_MAX) 63 के संकलन-समय की स्थिरता बनाएगा। हालांकि इस उदाहरण में हम एक हस्ताक्षरित प्रकार से काम कर रहे हैं, ताकि आपको साइन-बिट के लिए 1 खाते जोड़ना होगा यदि आप int64_t की वास्तविक चौड़ाई चाहते हैं, तो बिल्कुल 64 है

एक अलग comp.lang.c चर्चा में blargg नामक उपयोगकर्ता मैक्रो कैसे काम करता है का टूटना देता है:
पुन: प्री-प्रोसेसर का उपयोग करके पूर्णांक प्रकारों में बिट्स की गणना करने के लिए …

ध्यान दें कि मैक्रो केवल 2 ^ एन -1 मानों (यानी सभी 1 एस बाइनरी में) के साथ काम करता है, जैसा कि किसी भी MAX मान से अपेक्षित होगा यह भी ध्यान रखें कि एक अहस्ताक्षरित पूर्णांक प्रकार ( IMAX_BITS((unsigned type)-1) ) के अधिकतम मूल्य के लिए कंपाइल-टाइम स्थिरांक प्राप्त करना आसान है, लेकिन इस लेखन के समय मुझे कोई भी तरीका नहीं पता है क्रियान्वयन परिभाषित व्यवहार को लागू करने के बिना हस्ताक्षर किए पूर्णांक प्रकार के लिए एक ही बात। अगर मुझे कभी पता चल जाए तो मैं यहां अपने संबंधित एसओ प्रश्न का उत्तर दूंगा:
सी प्रश्न: ऑफ_टी (और अन्य हस्ताक्षरित पूर्णांक प्रकार) न्यूनतम और अधिकतम मूल्य – स्टैक ओवरफ़्लो

विशिष्ट पूर्णांक चौड़ाई के ज्ञात अधिकतम मूल्यों के विरुद्ध <limits.h> मैक्रोज़ की तुलना करें:

 #include <limits.h> #if UINT_MAX == 0xFFFF #define INT_WIDTH 16 #elif UINT_MAX == 0xFFFFFF #define INT_WIDTH 24 #elif ... #else #error "unsupported integer width" #endif 

पहला तरीका, यदि आप जानते हैं कि आपके पास किस प्रकार का मानक है (इसलिए आपका प्रकार टाइप टाइप नहीं है) {U}INT_MAX मैक्रोज़ के साथ जाएं और संभावित आकारों के खिलाफ जांच करें

यदि आपके पास ऐसा नहीं है, तो अहस्ताक्षरित प्रकारों के लिए यह अपेक्षाकृत आसान है, अवधारणात्मक रूप से। अपने पसंदीदा प्रकार T , बस (T)-1 और एक राक्षस परीक्षण मैक्रो करें जो कि सभी संभव मानों के विरुद्ध जांच करता है ?: चूंकि ये केवल समय के निरंतर अभिव्यक्ति को संकलित करते हैं, किसी भी सभ्य संकलक को अनुकूलन कर सकते हैं, जो आपको केवल उस मूल्य के साथ अवकाश देगा जो आप में रुचि रखते हैं।

यह प्रकार प्रकार के कारण #if आदि में काम नहीं करेगा, लेकिन यह एक सरल तरीके से नहीं बचा जा सकता है।

हस्ताक्षरित प्रकारों के लिए यह अधिक जटिल है। कम से कम प्रकार के int रूप में आप उस अहसासपूर्ण प्रकार को बढ़ावा देने के लिए एक चाल बनाने की उम्मीद कर सकते हैं और उस प्रकार की चौड़ाई प्राप्त कर सकते हैं। लेकिन यह जानने के लिए कि आपके हस्ताक्षरित प्रकार में सिर्फ एक ही मान थोड़ा कम है या नहीं, मुझे नहीं लगता कि यह जानने के लिए एक सामान्य अभिव्यक्ति है।

संपादित करें: बस इसे थोड़ा सा वर्णन करने के लिए, मैं इस दृष्टिकोण को (अहस्ताक्षरित प्रकार के लिए) बनाने के लिए आप क्या कर सकते हैं, इसके कुछ अंश देते हैं कि P99 में बहुत बड़ा अभिव्यक्ति नहीं उत्पन्न की मुझे कुछ पसंद है

 #ifndef P99_HIGH2 # if P99_UINTMAX_WIDTH == 64 # define P99_HIGH2(X) \ ((((X) & P00_B0) ? P00_S0 : 0u) \ | (((X) & P00_B1) ? P00_S1 : 0u) \ | (((X) & P00_B2) ? P00_S2 : 0u) \ | (((X) & P00_B3) ? P00_S3 : 0u) \ | (((X) & P00_B4) ? P00_S4 : 0u) \ | (((X) & P00_B5) ? P00_S5 : 0u)) # endif #endif #ifndef P99_HIGH2 # if P99_UINTMAX_WIDTH <= 128 # define P99_HIGH2(X) \ ((((X) & P00_B0) ? P00_S0 : 0u) \ | (((X) & P00_B1) ? P00_S1 : 0u) \ | (((X) & P00_B2) ? P00_S2 : 0u) \ | (((X) & P00_B3) ? P00_S3 : 0u) \ | (((X) & P00_B4) ? P00_S4 : 0u) \ | (((X) & P00_B5) ? P00_S5 : 0u) \ | (((X) & P00_B6) ? P00_S6 : 0u)) # endif #endif 

जहां जादू स्थैतिक को शुरुआत में #if के अनुक्रम के साथ परिभाषित किया जाता है वहां उन कंपलरों के लिए बहुत बड़ी स्थिरांक प्रदर्शित नहीं करना महत्वपूर्ण है, जो उन्हें संभाल नहीं सकते।

 /* The preprocessor always computes with the precision of uintmax_t */ /* so for the preprocessor this is equivalent to UINTMAX_MAX */ #define P00_UNSIGNED_MAX ~0u #define P00_S0 0x01 #define P00_S1 0x02 #define P00_S2 0x04 #define P00_S3 0x08 #define P00_S4 0x10 #define P00_S5 0x20 #define P00_S6 0x40 /* This has to be such ugly #if/#else to ensure that the */ /* preprocessor never sees a constant that is too large. */ #ifndef P99_UINTMAX_MAX # if P00_UNSIGNED_MAX == 0xFFFFFFFFFFFFFFFF # define P99_UINTMAX_WIDTH 64 # define P99_UINTMAX_MAX 0xFFFFFFFFFFFFFFFFU # define P00_B0 0xAAAAAAAAAAAAAAAAU # define P00_B1 0xCCCCCCCCCCCCCCCCU # define P00_B2 0xF0F0F0F0F0F0F0F0U # define P00_B3 0xFF00FF00FF00FF00U # define P00_B4 0xFFFF0000FFFF0000U # define P00_B5 0xFFFFFFFF00000000U # define P00_B6 0x0U # endif /* P00_UNSIGNED_MAX */ #endif /* P99_UINTMAX_MAX */ #ifndef P99_UINTMAX_MAX # if P00_UNSIGNED_MAX == 0x1FFFFFFFFFFFFFFFF # define P99_UINTMAX_WIDTH 65 # define P99_UINTMAX_MAX 0x1FFFFFFFFFFFFFFFFU # define P00_B0 0xAAAAAAAAAAAAAAAAU # define P00_B1 0xCCCCCCCCCCCCCCCCU # define P00_B2 0xF0F0F0F0F0F0F0F0U # define P00_B3 0xFF00FF00FF00FF00U # define P00_B4 0xFFFF0000FFFF0000U # define P00_B5 0xFFFFFFFF00000000U # define P00_B6 0x10000000000000000U # endif /* P00_UNSIGNED_MAX */ #endif /* P99_UINTMAX_MAX */ . . . 

हां, सभी व्यावहारिक उद्देश्यों के लिए, संभव चौड़ाई की संख्या सीमित है:

 #if ~0 == 0xFFFF # define INT_WIDTH 16 #elif ~0 == 0xFFFFFFFF # define INT_WIDTH 32 #else # define INT_WIDTH 64 #endif 

आप इसे रनटाइम पर सरल लूप, अच्छी तरह से परिभाषित और यूबी के खतरे के बिना गणना कर सकते हैं:

 unsigned int u; int c; for (c=0, u=1; u; c++, u<<=1); total_bits = CHAR_BIT * sizeof(unsigned int); value_bits = c; padding_bits = total_bits - value_bits; 

आपके यूनिट परीक्षणों में जांच करने के लिए सबसे सरल तरीका (आप उन्हें हैं, है ना?) कि value_bits आपकी वर्तमान INT_WIDTH परिभाषा के समान है

अगर आपको वास्तव में इसे संकलन के समय पर गणना करने की ज़रूरत है, तो मैं दिए गए # if- # elif cascades में से एक के साथ जाना होगा, या तो यूआईएनटीएमएक्स या आपके लक्ष्य प्रणाली का परीक्षण कर रहा है।

आपको ये किस लिए चाहिए? शायद यागनी?

एक सामान्य अवलोकन यह है कि यदि आप अपनी गणना में किसी डेटा प्रकार की चौड़ाई पर भरोसा करते हैं, तो आपको <stdint.h> उदाहरण uint32_t में स्पष्ट चौड़ाई डेटा प्रकार का उपयोग करना चाहिए।

मानक प्रकारों में बाइट्स की गिनती करने की कोशिश करने से यह सवाल है कि आपका 'पोर्टेबल' कोड ओवरफ़्लो की स्थिति में क्या करेगा।

आम तौर पर, int का आकार किसी दिए गए संकलक / प्लेटफ़ॉर्म के लिए जाना जाता है। यदि आपके पास मैक्रोज़ है जो कंपाइलर / प्लेटफ़ॉर्म की पहचान करता है, तो आप उन्हें INT_WIDTH को परिभाषित करने के लिए उपयोग कर सकते हैं।

आप उदाहरण के लिए <sys/types.h> और इसके आश्रितों को देख सकते हैं।