design - एक डेवलपर को किस बारे में पता होना चाहिए क्या उपयोगी बिटवाई ऑपरेटर कोड चालें?




language-agnostic bit-manipulation (8)

मुझे कहना होगा कि मेरे पास कभी भी बिटवाई ऑपरेटरों का उपयोग करने का कारण नहीं था, लेकिन मुझे यकीन है कि कुछ ऑपरेशन हैं जो मैंने किया है जो उनके साथ अधिक कुशलता से किया गया होता। "स्थानांतरण" और "OR-ing" ने आपको एक समस्या को और अधिक कुशलता से हल करने में कैसे मदद की है?


स्ट्रिंग्स (वर्ण) पर बिटवाईड ऑपरेशंस का उपयोग करना

पत्र को लोअरकेस में कनवर्ट करें:

  • OR अंतरिक्ष => (x | ' ')
  • परिणाम हमेशा लोअरकेस होता है भले ही पत्र पहले से ही कम हो
  • जैसे। ('a' | ' ') => 'a' ; ('A' | ' ') => 'a'

पत्र को अपरकेस में कनवर्ट करें:

  • AND अंडरलाइन => (x & '_')
  • परिणाम हमेशा अपरकेस होता है भले ही अक्षर पहले से ही अपरकेस है
  • जैसे। ('a' & '_') => 'A' ; ('A' & '_') => 'A'

उलटा पत्र का मामला:

  • अंतरिक्ष द्वारा XOR => (x ^ ' ')
  • जैसे। ('a' ^ ' ') => 'A' ; ('A' ^ ' ') => 'a'

वर्णमाला में पत्र की स्थिति :

  • AND chr(31) / binary('11111') / ( hex('1F') => (x & "\x1F")
  • परिणाम 1..26 रेंज में है, पत्र केस महत्वपूर्ण नहीं है
  • जैसे। ('a' & "\x1F") => 1 ; ('B' & "\x1F") => 2

वर्णमाला में अक्षर की स्थिति प्राप्त करें (केवल अपरकेस अक्षरों के लिए):

  • AND द्वारा ? => (x & '?') या XOR @ => (x ^ '@')
  • जैसे। ('C' & '?') => 3 ; ('Z' ^ '@') => 26

वर्णमाला में अक्षर की स्थिति प्राप्त करें (केवल लोअरकेस अक्षरों के लिए):

  • बैकटिक / chr(96) / binary('1100000') / hex('60') => (x ^ '`') द्वारा XOR
  • जैसे। ('d' ^ '`') => 4 ; ('x' ^ '`') => 25

नोट: अंग्रेजी अक्षरों के अलावा किसी अन्य चीज का उपयोग कचरा परिणाम देगा


1) 2 की शक्ति से विभाजित / गुणा करें

foo >>= x; (2 की शक्ति से विभाजित)

foo <<= x; (2 की शक्ति से गुणा)

2) स्वैप

x ^= y;
y = x ^ y;
x ^= y;

केवल तीन ही हैं जिन्हें मैंने कभी भी किसी भी आवृत्ति के साथ उपयोग किया है:

  1. थोड़ा सेट करें: ए | = 1 << बिट;

  2. थोड़ा साफ़ करें: एक & = ~ (1 << बिट);

  3. परीक्षण करें कि थोड़ा सेट है: एक और (1 << बिट);


प्रसिद्ध बिट ट्विडलिंग हैक्स देखें
अधिकांश गुणा / विभाजित वाले लोग अनावश्यक हैं - संकलक स्वचालित रूप से ऐसा करेंगे और आप लोगों को भ्रमित करेंगे।

लेकिन अगर आप हार्डवेयर या संचार प्रोटोकॉल के साथ काम करते हैं तो बहुत उपयोगी हैं, 'चेक / सेट / टॉगल बिट एन' प्रकार हैक का एक गुच्छा है।


मैंने bitstrings लिए दूरी गणना को प्रभावी ढंग से कार्यान्वित करने के लिए bitstrings ऑपरेटरों का उपयोग किया। मेरे अनुप्रयोग बिटरस्ट्रिंग में एक octree स्थान (एक octree , यदि आप रुचि रखते हैं, मॉर्टन ऑर्डरिंग के साथ एन्कोडेड) में पदों का प्रतिनिधित्व करने के लिए उपयोग किया जाता था। ग्रिड पर अंक किसी विशेष त्रिज्या के भीतर गिरने के बारे में जानने के लिए दूरी की गणना की आवश्यकता थी।


सेट बिट्स को गिनना, सबसे कम / उच्चतम सेट बिट ढूंढना, एनएचटी-टू-टॉप / नीचे सेट बिट ढूंढना और अन्य उपयोगी हो सकते हैं, और बिट-ट्विडलिंग हैक्स साइट को देखने लायक है।

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


मामले कम्प्यूटेशनल: विचार, एल्गोरिदम, स्रोत कोड, जोर्ग अर्न्त द्वारा (पीडीएफ) । इस पुस्तक में बहुत सी चीजें हैं, मैंने इसे http://www.hackersdelight.org/ पर एक लिंक के माध्यम से पाया

ओवरफ्लो के बिना औसत

एक्स और वाई दो तर्कों के औसत (x + y) / 2 की गणना के लिए एक दिनचर्या है

static inline ulong average(ulong x, ulong y)
// Return floor( (x+y)/2 )
// Use: x+y == ((x&y)<<1) + (x^y)
// that is: sum == carries + sum_without_carries
{
    return (x & y) + ((x ^ y) >> 1);
}

  • पूर्णांक पर बिटवाई ऑपरेशंस (int)

अधिकतम पूर्णांक प्राप्त करें

int maxInt = ~(1 << 31);
int maxInt = (1 << 31) - 1;
int maxInt = (1 << -1) - 1;

न्यूनतम पूर्णांक प्राप्त करें

int minInt = 1 << 31;
int minInt = 1 << -1;

अधिकतम लंबा प्राप्त करें

long maxLong = ((long)1 << 127) - 1;

2 से गुणा किया गया

n << 1; // n*2

2 से विभाजित

n >> 1; // n/2

2 की एम-वें शक्ति से गुणा किया गया

n << m;

2 की एम-वें शक्ति द्वारा विभाजित

n >> m;

अजीब संख्या की जांच करें

(n & 1) == 1;

दो मानों का आदान-प्रदान करें

a ^= b;
b ^= a;
a ^= b;

पूर्ण मूल्य प्राप्त करें

(n ^ (n >> 31)) - (n >> 31);

अधिकतम दो मान प्राप्त करें

b & ((a-b) >> 31) | a & (~(a-b) >> 31);

दो मानों का न्यूनतम प्राप्त करें

a & ((a-b) >> 31) | b & (~(a-b) >> 31);

जांचें कि दोनों के पास एक ही संकेत है या नहीं

(x ^ y) >= 0;

2 ^ एन की गणना करें

2 << (n-1);

चाहे 2 का कारखाना है

n > 0 ? (n & (n - 1)) == 0 : false;

एम के खिलाफ मॉडुलो 2 ^ एन

m & (n - 1);

औसत प्राप्त करें

(x + y) >> 1;
((x ^ y) >> 1) + (x & y);

एम के एम-वें बिट प्राप्त करें (निम्न से उच्च तक)

(n >> (m-1)) & 1;

एन -0 के एम-वें बिट को सेट करें (निम्न से उच्च तक)

n & ~(1 << (m-1));

एन + 1

-~n

एन -1

~-n

विपरीत संख्या प्राप्त करें

~n + 1;
(n ^ -1) + 1; 

अगर (एक्स == ए) एक्स = बी; अगर (एक्स == बी) एक्स = ए;

x = a ^ b ^ x;




bit