मैं बिटवाई ऑपरेशंस को समझता हूं और विभिन्न प्रयोजनों के लिए वे कैसे उपयोगी हो सकते हैं, उदा। अनुमतियाँ। हालांकि, मुझे समझ में नहीं आता कि बिट शिफ्ट ऑपरेटरों का क्या उपयोग होता है। मैं समझता हूं कि वे कैसे काम करते हैं, लेकिन मैं उन परिदृश्यों के बारे में नहीं सोच सकता जहां मैं उनका उपयोग करना चाहूंगा, जब तक कि मैं कुछ वास्तव में त्वरित गुणा या विभाजन नहीं करना चाहता। क्या बिट-स्थानांतरण का उपयोग करने के कोई अन्य कारण हैं?त्वरित गणित को छोड़कर बिट स्थानांतरण का उपयोग करने के कोई अच्छे कारण हैं?
उत्तर
कई कारण हैं, कुछ कर रहे हैं यहाँ:
- मान लीजिए कि आप बिट्स के एक दृश्य के रूप में एक काले और सफेद छवि का प्रतिनिधित्व करता है और आपके सामान्य रूप से इस छवि में एक भी पिक्सेल सेट करना चाहते हैं। उदाहरण के लिए आपका बाइट ऑफसेट x >> 3 हो सकता है और आपका बिट ऑफसेट x & 0x7 हो सकता है और आप इसे बिट द्वारा सेट कर सकते हैं: byte = byte | (1 < < (x & 0x7));
- डेटा संपीड़न एल्गोरिदम लागू करना जहां आप परिवर्तनीय लंबाई बिट अनुक्रमों से निपटते हैं, उदा। हफमैन कोडिंग।
- आप कुछ हार्डवेयर के साथ बातचीत कर रहे हैं, उदा। एक धारावाहिक संचार उपकरण, और आपको कुछ नियंत्रण बिट्स को पढ़ने या सेट करने की आवश्यकता है।
उन और अन्य कारणों से अधिकांश प्रोसेसर में थोड़ा बदलाव और/या रोटेशन निर्देशों के साथ-साथ अन्य तर्क निर्देश (और/या/xor/नहीं) हैं। के रूप में वे और अधिक जटिल आपरेशनों हैं
ऐतिहासिक गुणा और भाग काफी धीमी थे और कुछ सीपीयू पर उन सभी नहीं था।
इसके अलावा यहाँ देखें: Have you ever had to use bit shifting in real projects?
जैसा कि आप इंगित करते हैं, बाएं शिफ्ट दो गुणा के समान ही है। कम से कम यह तब होता है जब हम हस्ताक्षरित मात्राओं के बारे में बात कर रहे हैं। एक हस्ताक्षरित मात्रा के "बाएं शिफ्ट" का अर्थ है ... भाषा निर्भर।
आधुनिक कंपाइलर्स के साथ, "i = x * 2" लिखने के बीच वास्तव में कोई अंतर नहीं है; और "i = x < < 1;" कंपाइलर सबसे कुशल कोड उत्पन्न करेगा। तो उस अर्थ में गुणा करने के लिए शिफ्ट पसंद करने का कोई कारण नहीं है।
कुछ एल्गोरिदम एक मात्रा एक बिट द्वारा छोड़ा स्थानांतरण और करने के लिए या तो 0 या 1. कुछ सरल संपीड़न एल्गोरिदम इस तरह से काम करते हैं तो कम बिट की स्थापना करके काम करते हैं। उदाहरण के लिए, यदि आपका संचित मान चर x में है, और वर्तमान मान (0 या 1) y में है, तो यह "x = (x < < 1) | y" लिखने के लिए अधिक समझ में आता है, "x" के बजाय = (एक्स * 2) + वाई "। दोनों एक ही काम करते हैं, लेकिन पहले उल्लेखनीय रूप से सही है। आपको यह सोचने की ज़रूरत नहीं है, "ओह, ठीक है, दो गुना गुना एक बाएं शिफ्ट के समान है।"
इसके अलावा, जब आप बिट्स को स्थानांतरित करने वाले एल्गोरिदम के बारे में बात कर रहे हैं, तो यह पता लगाने के लिए कि आप कितने 2 गुणा करना चाहते हैं या विभाजित करना चाहते हैं, एक बिट संख्या के साथ बाएं या दाएं स्थानांतरित करना अधिक सुविधाजनक है।
तो, जबकि आमतौर पर गुणा करने के बजाए स्थानांतरित करने के लिए कोई प्रदर्शन लाभ नहीं होता है - कम से कम नहीं जब उच्च स्तर की भाषाओं के साथ काम करते हैं - ऐसे समय होते हैं जब शिफ्ट करने की क्षमता होती है जो आप आसानी से समझ रहे हैं।
वहाँ स्थानों पर जहां थोड़ा बदलाव संचालन नियमित रूप से संख्यात्मक गणनाओं में उनके उपयोग के बाहर उपयोग किया जाता है की बहुत कुछ कर रहे हैं। उदाहरण के लिए, Bitboard एक डेटा संरचना है जिसका उपयोग आमतौर पर बोर्ड के प्रतिनिधित्व के लिए बोर्ड गेम में किया जाता है।कुछ सबसे मजबूत शतरंज इंजन मुख्य रूप से गति और गति उत्पादन और मूल्यांकन की आसानी के लिए इस डेटा संरचना का उपयोग करते हैं। ये कार्यक्रम बिट ऑपरेशंस का भारी उपयोग करते हैं और बिट-शिफ्ट ऑपरेशंस का विशेष रूप से कई संदर्भों में उपयोग किया जाता है - जैसे बिट मास्क ढूंढना, बोर्ड पर नई चालें उत्पन्न करना, लॉगरिदम को बहुत जल्दी कंप्यूटिंग करना आदि। यहां तक कि बहुत उन्नत संख्यात्मक गणना भी हो सकती है बिट ऑपरेशंस के चालाक उपयोग से खूबसूरती से किया। थोड़ा twiddling हैक्स के लिए this site देखें - उनमें से बहुत से एल्गोरिदम शिफ्ट ऑपरेटरों का उपयोग करते हैं। बिट शिफ्ट ऑपरेशंस नियमित रूप से डिवाइस ड्राइवर प्रोग्रामिंग, कोडेक विकास, एम्बेडेड सिस्टम प्रोग्रामिंग आदि में उपयोग किए जाते हैं।
स्थानांतरण एक चर के भीतर विशिष्ट बिट्स तक पहुंचने की अनुमति देता है। अभिव्यक्ति (n >> p) & ((1 << m) - 1)
n
के दाईं ओर p
बिट्स के ऑफसेट के साथ m
-बिट भाग को पुनर्प्राप्त करता है।
यह आपके प्रोग्राम को पूर्णांक का उपयोग करने की अनुमति देता है जो 8 बिट्स के गुणक नहीं हैं, जो डेटा संपीड़न के लिए उपयोगी है।
उदाहरण के लिए, मैंने इसे Netflix Prize प्रोग्रामों में रिकॉर्ड्स पैक करने के लिए उपयोग किया (22-बिट उपयोगकर्ता आईडी + 15-बिट मूवी आईडी + 12-बिट डेट + 3-बिट रेटिंग) uint64_t
(12 बिट्स को छोड़कर) ।
एक बहुत आम विशेष मामला प्रत्येक बाइट में 8 bool
चर पैक करना है। (यूनिक्स फ़ाइल अनुमतियां, ब्लैक-एंड-व्हाइट बिटमैप्स, CPU flags registers, आदि)
इसके अलावा, बिट मैनिपुलेशन का उपयोग UTF-8 में किया जाता है, जो एक बहुत लोकप्रिय चरित्र एन्कोडिंग है। यूनिकोड वर्णों को उनके बिट्स को 1, 2, 3, या 4 बाइट्स में वितरित करके दर्शाया जाता है।
संभावित डुप्लिकेट [क्या आपने कभी वास्तविक परियोजनाओं में थोड़ा स्थानांतरण करने का उपयोग किया है?] (Http://stackoverflow.com/questions/520625/have-you-ever-had-to-use-bit-shifting-in -real-projects) – dan04
संभावित डुप्लिकेट [बिटवाई शिफ्ट (बिट-शिफ्ट) ऑपरेटर क्या हैं और वे कैसे काम करते हैं?] (http://stackoverflow.com/questions/141525/what-are-bitwise-shift-bit- पारी ऑपरेटरों और कैसे करते हैं-वे काम) –