सवाल "Int मुखौटा = ~ 0;" का उद्देश्य क्या है?


मैंने कोड की निम्नलिखित पंक्ति देखी यहाँ सी में

 int mask = ~0;

मैंने इसका मूल्य मुद्रित किया है mask सी और सी ++ में। यह हमेशा प्रिंट करता है -1

तो मेरे पास कुछ प्रश्न हैं:

  • मूल्य असाइन क्यों करें ~0 को मुखौटा चर?
  • का उद्देश्य क्या है ~0?
  • क्या हम उपयोग कर सकते हैं -1 के बजाय ~0?

44
2017-09-23 06:19


मूल


~0 केवल बराबर है -1 2 के पूरक में - phuclv
@PaulFloyd: लिंक्ड स्रोत एक शुद्ध बिट-फिडलिंग अभ्यास के बारे में है ... वजन उठाने के रूप में उपयोगी है - 6502
सम्बंधित: क्या सभी बिट्स को सत्य पर सेट करने के लिए -1 का उपयोग करना सुरक्षित है? - Cody Gray♦
मास्क के लिए हस्ताक्षरित प्रकार का उपयोग करने से मुझे पता चलता है कि आपके कोड में भयानक चीजें हैं। - Sopel
के संभावित डुप्लिकेट ऑपरेटर क्या करता है? - Dukeling


जवाब:


वर्तमान आर्किटेक्चर पर पूर्णांक में कितने बिट्स हैं, यह जानने के बिना यह सभी बाइनरी बिट्स को 1 बिट्स के पूर्णांक में सेट करने का एक पोर्टेबल तरीका है।


78
2017-09-23 06:22



-1 चौड़ाई को जानने के बिना सभी बिट्स को एक पूर्णांक में 1 सेट भी करता है int प्रकार। यह सिर्फ दो पूरक के उपयोग का तात्पर्य है - phuclv
@ LưuVĩnhPhúc सही। ~ 0 विधि में कम निर्भरताएं हैं। हस्ताक्षर किए गए, गैर-दो की तारीफ प्रणालियों पर काम करता है और (तर्कसंगत) कम गुप्त है। - Richard Hodges
@chqrlie क्यों नहीं? बिटमैस्क के लिए हस्ताक्षरित मानों का उपयोग कर बीटीडब्ल्यू एक अजीब विचार है। - P__J__
@ पीटरजे_01: अगर long की तुलना में अधिक बिट्स है int, फिर ~0u (जिसमें प्रकार है unsigned) होने वाला शून्य बढ़ाया प्रारंभ करने के हिस्से के रूप में u। - Henning Makholm
यह किसी के पूरक पर पोर्टेबल नहीं है: यह ऋणात्मक शून्य देता है, जो एक अनुरूप संकलक निर्णय ले सकता है एक जाल प्रतिनिधित्व है। उस समय आपके पास यूबी है। निष्पक्ष होने के लिए, ऐसा कार्यान्वयन नहीं कहा जा सकता है है सभी के लिए मूल्य int पहली जगह में। - Kevin


सी और सी ++ 3 अलग-अलग हस्ताक्षरित पूर्णांक प्रारूपों की अनुमति देते हैं: साइन-परिमाण, एक पूरक और दो पूरक

~0 सभी एक बिट्स का उत्पादन करेगा साइन प्रारूप के बावजूद प्रणाली का उपयोग करता है। तो यह अधिक पोर्टेबल से -1

आप जोड़ सकते हैं U प्रत्यय (यानी -1U) एक-एक बिट पैटर्न उत्पन्न करने के लिए portably1। तथापि ~0  मंशा स्पष्ट स्पष्ट इंगित करता है: मूल्य 0 में सभी बिट्स को घुमाएं जबकि -1 दिखाएगा कि शून्य के मूल्य की आवश्यकता है, न कि इसके द्विआधारी प्रतिनिधित्व

1 क्योंकि हस्ताक्षरित ऑपरेशन हमेशा होते हैं मॉड्यूल को कम करें जो कि सबसे बड़ा मान से अधिक है जिसे परिणामी प्रकार से दर्शाया जा सकता है


37
2017-09-23 06:23



पाठ कहता है कि 2 के पूरक 32-बिट पूर्णांक को माना जा सकता है - 6502


यह एक 2 के पूरक मंच (जिसे माना जाता है) पर आपको -1 देता है, लेकिन लेखन -1 नियमों द्वारा सीधे निषिद्ध है (केवल पूर्णांक 0..255, यूनरी !, ~ और बाइनरी &, ^, |, +, << तथा >> अनुमति हैं)।


8
2017-09-23 06:30





आप दिए गए कार्यों को करने के लिए ऑपरेटरों और भाषा निर्माण पर कई प्रतिबंधों के साथ एक कोडिंग चुनौती का अध्ययन कर रहे हैं।

पहली समस्या है मान -1 वापस करें के उपयोग के बिना - ऑपरेटर।

उन मशीनों पर जो नकारात्मक संख्याओं को दो पूरक के साथ दर्शाते हैं, मूल्य -1 सेट सभी बिट्स के साथ प्रतिनिधित्व किया जाता है 1, इसलिए ~0 का मूल्यांकन -1:

/* 
 * minusOne - return a value of -1 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 2
 *   Rating: 1
 */
int minusOne(void) {
  // ~0 = 111...111 = -1
  return ~0;
}

फ़ाइल में अन्य समस्याएं हमेशा सही ढंग से लागू नहीं होती हैं। दूसरी समस्या, एक बूलियन मूल्य लौटने से तथ्य का प्रतिनिधित्व करता है int मूल्य 16 बिट हस्ताक्षरित में फिट होगा short एक दोष है:

/* 
 * fitsShort - return 1 if x can be represented as a 
 *   16-bit, two's complement integer.
 *   Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 8
 *   Rating: 1
 */
int fitsShort(int x) {
  /* 
   * after left shift 16 and right shift 16, the left 16 of x is 00000..00 or 111...1111
   * so after shift, if x remains the same, then it means that x can be represent as 16-bit
  */
  return !(((x << 16) >> 16) ^ x); 
}

एक ऋणात्मक मूल्य या एक संख्या को स्थानांतरित करना छोड़ दिया गया है जिसका स्थानांतरित मूल्य सीमा से परे है int अपरिभाषित व्यवहार है, सही मूल्य को स्थानांतरित करना कार्यान्वयन परिभाषित किया गया है, इसलिए उपर्युक्त समाधान गलत है (हालांकि यह संभवतः अपेक्षित समाधान है)।


5
2017-09-23 13:49





लूओंग पहले यह था कि आपने 1K ZX 80 या ZX 81 कंप्यूटर जैसे बेहद सीमित उपकरणों पर स्मृति को कैसे बचाया। बेसिक में, आप करेंगे

Let X = NOT PI

बजाय

LET X = 0

चूंकि संख्याओं को 4 बाइट फ्लोटिंग पॉइंट्स के रूप में संग्रहीत किया गया था, बाद वाले पहले पीआई विकल्प से 2 बाइट अधिक लेते हैं, जहां प्रत्येक और पीआई एक बाइट लेता है।


2
2017-09-23 20:17



बिल्कुल नहीं। उन उदाहरणों में सभी (कुंजी) शब्दों को एकल बाइट्स द्वारा एन्कोड किया गया था, साथ ही बराबर चिह्न, परिवर्तनीय नाम और दिखाई शून्य खुद हालांकि, संख्यात्मक स्थिरांक के बाद (एक बचाना बाइट?) प्लस 4-बाइट फ़्लोटिंग-पॉइंट मान, जिसे निष्पादक द्वारा उपयोग किया गया था लेकिन स्रोत में नहीं दिखाया गया था। इसलिए यहां आकार की दुविधा 3 या 4 बाइट्स है, 2 नहीं। - CiaPan
मुझे काम करना चाहिए ... बस कुछ जेएक्स स्पेक्ट्रम एमुलेटर पर किया और इसे टेप / डिस्क में सहेजा। पहला वाला 40 और सीन्ड 35 बाइट्स का उपयोग करता है, इसलिए 5 बाइट अंतर। खैर, अगर आपके पास जेडएक्स 81 पर सिर्फ 1k है, तो मुझे लगता है कि फ़ाइल आकार में आधा प्रतिशत बचत है और यही कारण है कि इसका उपयोग किया गया था ... ओपी प्रश्न पर वापस - क्या आप एक बाइट या दो सहेजने में सक्षम होंगे (या 5) आज x = -1 के बजाय x = ~ 0 का उपयोग करके? शायद एक रूपांतरण का उपयोग कर रहे हैं जैसे कि लंबे x = ~ 0? - skaak
मुझे वास्तव में काम करना चाहिए ... बस कुछ सरल तरीकों से सी में इसका प्रयास किया गया लेकिन संकलित फ़ाइल -1, ~ 0 और ~ (0x00) के लिए एक ही आकार थी ... मुझे यकीन है कि कुछ आर्किटेक्चर हैं जहां यह होगा एक बाइट या तो बचाओ लेकिन आजकल इस तरह की विषमताओं को हर कीमत पर टालना चाहिए। संकलित फाइलें लगभग 8.5k बाइट थीं। यह गरीब ZX81 को दिल का दौरा देगा ... - skaak
आधुनिक सी कंपाइलर्स पहचानने के लिए पर्याप्त स्मार्ट हैं ~0 तथा -1 एक ही मूल्य के रूप में। वे कोड को अधिकतम गति या न्यूनतम आकार तक अनुकूलित भी कर सकते हैं, इसलिए आपको संकलन विकल्पों के साथ खेलना होगा। इसके अलावा, संकलित कोड को फ़ंक्शन के प्रवेश बिंदुओं के बेहतर संरेखण के लिए 4, 8 या 16 बाइट तक गोल किया जा सकता है, इसलिए देख रहे हैं obj फ़ाइल आकार आपके पुस के लिए अनुपयुक्त है। आप अपने कोड के बाइट-बाय-बाइट प्रतिनिधित्व को देखने के लिए संकलित ऑब्जेक्ट मॉड्यूल (कुछ टूल जैसे objdump) को असेंबली में सी कोड संकलित कर सकते हैं, या यहां तक ​​कि डिस्सेबल कर सकते हैं। - CiaPan
क्या उन प्रणालियों पर कोई पूर्णांक प्रकार नहीं है? और कैसे कर सकते हैं PI एक बाइट में संग्रहीत किया जाना चाहिए? - phuclv


सभी कंप्यूटर आर्किटेक्चर में एन्कोडिंग संख्याओं के कई तरीके हैं। 2 के पूरक का उपयोग करते समय यह हमेशा सत्य होगा:~0 == -1। दूसरी ओर, कुछ कंप्यूटर नकारात्मक संख्या को एन्कोड करने के लिए 1 के पूरक का उपयोग करते हैं जिसके लिए उपरोक्त उदाहरण असत्य है, क्योंकि ~0 == -0। हाँ, 1 एस पूरक में नकारात्मक शून्य है, और यही कारण है कि यह बहुत सहज नहीं है।

तो आपके सवालों के लिए

  • ~ 0 को मास्क को सौंपा गया है, इसलिए मास्क में सभी बिट्स बराबर 1 -> बनाने के बराबर हैं mask & sth == sth
  • इस्तेमाल किए गए मंच के बावजूद ~ 0 का उपयोग सभी बिट्स को 1 के बराबर बनाने के लिए किया जाता है
  • यदि आप सुनिश्चित हैं कि आपका कंप्यूटर प्लेटफार्म 2 के पूरक संख्या एन्कोडिंग का उपयोग करता है तो आप ~ 0 के बजाय -1 का उपयोग कर सकते हैं

मेरा व्यक्तिगत विचार - अपना कोड उतना ही प्लेटफॉर्म-स्वतंत्र बनाएं जितना आप कर सकते हैं। लागत अपेक्षाकृत छोटी है और कोड असफल साबित हो जाता है


0
2017-09-23 12:46



केवल अगर 1 एस पूरक कार्यान्वयन नकारात्मक शून्य का समर्थन करता है। यह भी देखें यह जवाब - JHBonarius