इंक्रीमेंटिंग 'नकाबपोश' बिटसेट्स


81

मैं वर्तमान में एक ट्री एन्यूमरेटर लिखने की प्रक्रिया में हूँ जहाँ मैं निम्नलिखित समस्या के लिए आया हूँ:

मैं नकाबपोश बिटसेट्स देख रहा हूं, यानी बिटसेट्स जहां सेट बिट्स मास्क का एक उपसमूह है, यानी 0000101मास्क के साथ 1010101। जो मैं पूरा करना चाहता हूं वह बिटसेट बढ़ाना है, लेकिन केवल नकाबपोश बिट्स के संबंध में। इस उदाहरण में, परिणाम होगा 0010000। इसे थोड़ा स्पष्ट करने के लिए, केवल नकाबपोश बिट्स निकालें, यानी 0011उन्हें बढ़ाएं 0100और उन्हें मास्क बिट्स को फिर से वितरित करें, दे 0010000

क्या किसी को भी ऐसा करने का एक कुशल तरीका दिखाई देता है, बिटकॉन्स और उपसर्ग मास्क के संयोजन का उपयोग करते हुए ऑपरेशन को हाथ से करने की कमी?

जवाबों:


123

बस नॉन मास्क बिट्स को अपने साथ भरें ताकि वे कैरी का प्रचार करें:

// increments x on bits belonging to mask
x = ((x | ~mask) + 1) & mask;

11
यह एक अच्छी चाल है ... लगभग मैंने कहा जादू है कोई नहीं है :)
यूजीन श्री।

8
@ यूजीनश। कभी विश्वास मत करो कि ऐसा नहीं है।
zch

24
संभवतः ओपी के लिए महत्वपूर्ण नहीं है क्योंकि वे स्वीकार करते हैं, लेकिन शायद यह ध्यान दिया जाना चाहिए कि यह गैर-मुखौटा बिट्स को शून्य कर देगा। अगर वे कर रहे थे कहीं और की जरूरत है, तो आप और अधिक सावधान की जगह होने के लिए होगा x। संभवतः x = (x & ~mask) | (((x | ~mask) + 1) & mask);
त्रिपुंड

2
@ ट्राइ हाउंड अगर उन्हें ज़रूरत नहीं होती, तो एक बिट मास्क का उपयोग करने से भी क्या होगा?
someonewithpc

1
@someonewithpc यकीन नहीं होता कि आप क्या कहना / पूछना चाह रहे हैं। मुझे नहीं पता कि ओपी को बिट्स के गैर-आसन्न सेट को बढ़ाने की आवश्यकता क्यों है, इसलिए मुझे नहीं पता कि मूल मूल्य में अन्य बिट्स हैं या नहीं। उदाहरण के लिए, यदि मूल मूल्य थे 0101101(जैसे .1.1.0.कि गैर-मुखौटा बिट्स और 0.0.1.1"काउंटर" में) तो क्या उन्हें संरक्षण करते समय (नए "काउंटर" की आवश्यकता होगी ) या बस स्वीकार्य है। यह उत्तर (और शायद अन्य, हालांकि मैंने जाँच नहीं की है) उत्तरार्द्ध देते हैं; यदि आवश्यक हो तो मेरे संस्करण को पूर्व देना चाहिए। 01110000.1.0.0.1.1.0.0010000
ट्रिपहाउंड

20

स्वीकार किए गए उत्तर की तुलना में सहज नहीं है, यह केवल 3 चरणों में काम करता है:

x = -(x ^ mask) & mask;

इसे zch द्वारा सुझाए अनुसार सत्यापित किया जा सकता है:

  -(x ^ mask)
= ~(x ^ mask) + 1  // assuming 2's complement
= (x ^ ~mask) + 1
= (x | ~mask) + 1  // since x and ~mask have disjoint set bits

फिर यह स्वीकृत उत्तर के बराबर हो जाता है।


2
ज़च द्वारा जवाब बहुत सहज है, मैं तुरंत देख सकता हूं कि यह उसकी स्पष्ट व्याख्या के कारण सही है। इस उत्तर का तर्क क्या है? वांछित प्रभाव देने के लिए यह सूत्र कैसे काम करता है? मैं खोज की प्रक्रिया के बारे में उत्सुक हूं, यहां अंतर्दृष्टि की प्रकृति।
FooF

मुझे लगता है कि आपका सत्यापन बहुत सरल होगा यदि आपने अभी साबित किया है कि -(x ^ mask) == (x | ~mask) + 1जब भी एक्स मास्क का सबसेट होता है और तब मेरे उत्तर को संदर्भित किया जाता है।
zch

5
-(x^mask) == ~((x ^ mask) - 1) == ~(x ^ mask) + 1 == (x ^ ~mask) + 1 == (x | ~mask) + 1। अंतिम समीकरण धारण करता है क्योंकि बिटसेट्स असमान हैं, अन्य हमेशा सही होते हैं (कम से कम 2-पूरक में)।
zch

1
जो लोग इस उत्तर को प्राप्त करने के लिए उठाए गए कदमों के बारे में उत्सुक हैं, वे इस पृष्ठ का उल्लेख कर सकते हैं ।
नंगे

5
शायद यह इंगित करने के लायक है कि ये उसी का अनुकूलन नहीं करते हैं, जो अक्सर बिट- ट्विडलिंग करने वाले लोगों के लिए प्रासंगिक होता है: Godbolt.org/g/7VWXas - हालांकि जो वास्तव में छोटा है वह कंपाइलर पर निर्भर करता है। कोई भी विचार जो तेज होगा या यदि अंतर महत्वपूर्ण है।
लेउशेंको

7

यदि पुनरावृत्ति का क्रम इतना महत्वपूर्ण नहीं है, और एक विकृति ऑपरेशन आपकी आवश्यकताओं को पूरा करेगा, तो केवल दो संचालन का उपयोग करना संभव है:

चलो साथ - साथ शुरू करते हैं

x = mask

और पिछले मूल्य के साथ मिलता है

x = (x - 1) & mask

x - 1भाग पिछले गैर-शून्य बिट को शून्य में बदलता है, और सभी कम महत्वपूर्ण बिट्स को 1 में सेट करता है। फिर & maskउनमें से केवल मुखौटा बिट्स को छोड़ देता है।


2 ऑप्स, अच्छा है। मैं तर्क दूंगा कि यह एक ही दृष्टिकोण है, केवल शून्य के माध्यम से उधार का प्रचार करना है, बजाय लोगों के माध्यम से ले जाने के बजाय।
22

@zch, यह सही है, धन्यवाद। मैं जवाब दूंगा
DALE

केवल तभी काम करता है जब x सभी गैर-मुखौटा बिट्स के साथ शुरू होता है।
जैसन

@ जासेन, ज़रूर। लेकिन उन गैर-मुखौटा बिट्स को सेट करना मुश्किल नहीं है। और अन्य उत्तरों में समान मुद्दा है।
डेले
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.