क्या आपने कभी वास्तविक प्रोग्रामिंग परियोजनाओं में बिट शिफ्टिंग का उपयोग किया है? अधिकांश (यदि सभी नहीं) उच्च स्तर की भाषाओं में शिफ्ट ऑपरेटर होते हैं, लेकिन आपको वास्तव में उनका उपयोग करने की आवश्यकता कब होगी?
क्या आपने कभी वास्तविक प्रोग्रामिंग परियोजनाओं में बिट शिफ्टिंग का उपयोग किया है? अधिकांश (यदि सभी नहीं) उच्च स्तर की भाषाओं में शिफ्ट ऑपरेटर होते हैं, लेकिन आपको वास्तव में उनका उपयोग करने की आवश्यकता कब होगी?
जवाबों:
मैं अभी भी उन प्रणालियों के लिए कोड लिखता हूं जिनमें हार्डवेयर में फ्लोटिंग पॉइंट सपोर्ट नहीं है। इन प्रणालियों में आपको लगभग अपने सभी अंकगणित के लिए बिट-शिफ्टिंग की आवश्यकता होती है।
साथ ही आपको हैश जनरेट करने के लिए शिफ्ट्स की जरूरत होती है। बहुपद अंकगणित (CRC, रीड-सोलोमन कोड मुख्य धारा के अनुप्रयोग हैं) या पाली का भी उपयोग करता है।
हालाँकि, पाली का उपयोग केवल इसलिए किया जाता है क्योंकि वे काम कर रहे हैं और बिल्कुल वही व्यक्त करते हैं जो लेखक का इरादा था। यदि आप चाहते हैं तो आप गुणा-भाग के साथ सभी बिट-शिफ्ट का अनुकरण कर सकते हैं, लेकिन यह लिखना कठिन होगा, कम पठनीय और कभी-कभी धीमा।
कंपाइलर उन मामलों का पता लगाते हैं जहां गुणा को एक शिफ्ट में कम किया जा सकता है।
हां, मैंने उनका कई बार इस्तेमाल किया है। बिट ट्विडलिंग एम्बेडेड हार्डवेयर पर महत्वपूर्ण है जहां बिट-मास्क बहुत आम हैं। गेम प्रोग्रामिंग में भी यह महत्वपूर्ण है, जब आपको हर अंतिम प्रदर्शन की आवश्यकता होती है।
संपादित करें: इसके अलावा, मैं उन्हें बिटमैप्स में हेरफेर करने के लिए बहुत उपयोग करता हूं, उदाहरण के लिए रंग की गहराई को बदलना, या RGB <-> BGR को परिवर्तित करना।
और मैं कई मामलों के बारे में नहीं सोच सकता जब उनका उपयोग किया जा रहा है। यह आमतौर पर अन्य तरह से होता है - कुछ विशिष्ट समस्या है, और यह पता चलता है कि बिट संचालन को नियोजित करने से सर्वोत्तम परिणाम प्राप्त होंगे (आमतौर पर प्रदर्शन के समय में - समय और / या स्थान)।
short
में एक int
ईगर फ़ील्ड में दो s स्टोर करने की आवश्यकता हो सकती है । साथ ही सत्र में दो मानों को संग्रहीत करने का मेमोरी ओवरहेड सहेजा जाता है।
एक जगह मैं उन्हें हर समय उपयोग करता हूं जब क्रॉस-प्लेटफ़ॉर्म अनुप्रयोगों के लिए पूर्णांकों के एंडियन-नेस को ट्रांसप्लांट किया जाता है। वे कभी-कभी 2 डी ग्राफिक्स ब्लिटिंग के दौरान (अन्य बिट-मैनिपुलेशन ऑपरेटरों के साथ) काम में आते हैं।
मैंने उन्हें कुछ बार उपयोग किया है, लेकिन हमेशा एक बाइनरी फ़ाइल प्रारूप को पार्स करने के लिए।
बिट शिफ्ट तेज हैं। वे सीपीयू अनुदेश सेट में डिवीजन और मापुलस संचालन से बहुत पहले लागू किए गए थे। हम में से कई ने अंकगणित के लिए बिट शिफ्ट का उपयोग किया है जो पेंसिल और कागज पर सरल है, लेकिन हमारे सीपीयू पर उपलब्ध नहीं है।
उदाहरण के लिए:
हां, अभी भी इसकी जरूरत है।
उदाहरण के लिए मेरी नौकरी में हम सीरियल पोर्ट COMx के माध्यम से पीएलसी के साथ संचार के लिए सॉफ्टवेयर विकसित करते हैं। एक बाइट के भीतर बिट्स को संभालना आवश्यक है, हम शिफ्ट लेफ्ट / राइट का उपयोग करते हैं, और लॉजिक ऑपरेटर OR, XOR, और दिन-प्रतिदिन।
उदाहरण के लिए, मान लें कि हमें बाइट के बिट 3 (दाएं से बाएं) पर मुड़ना है:
यह करने के लिए बहुत अधिक कुशल है:
Byte B;
B := B XOR 4;
के बजाय:
Byte B = 0;
String s; // 0 based index
s = ConvertToBinary (B);
s[5] = "1";
B := ConvertToDecimal (s);
सादर।
जब मैंने असेंबली लैंग्वेज में लिखा, तो मेरा कोड बिट-शिफ्टिंग और मास्किंग से भरा था।
क्या यह सी में एक उचित राशि है, साथ ही।
इसे जावास्क्रिप्ट या सर्वर भाषाओं में बहुत अधिक नहीं किया गया है।
संभवतः सबसे अच्छा आधुनिक उपयोग बूलियन मूल्यों के एक पैक सरणी के माध्यम से कदम है जो लोगों और शून्य के रूप में प्रतिनिधित्व करते हैं। मैं हमेशा असेंबली में साइन बिट के लिए शिफ्ट और चेक को छोड़ देता था, लेकिन उच्च स्तर की भाषाओं में आप एक मूल्य के खिलाफ तुलना करते हैं।
उदाहरण के लिए, यदि आपके पास 8 बिट्स हैं, तो आप "if (a> 127) {...}" के साथ शीर्ष बिट की जांच करते हैं। फिर आपने शिफ्ट छोड़ दिया (या 2 से गुणा करें), 127 के साथ एक "और" (या यदि अंतिम बिट सेट किया गया था, तो 256 का घटाव करें), और इसे फिर से करें।
मैंने उन्हें छवि संपीड़न / अपघटन में बहुत उपयोग किया, जहां बिटमैप में बिट्स संपीड़ित थे। Http://en.wikipedia.org/wiki/Huffman_coding का उपयोग करके चीजों को संपीड़ित किया जाना विभिन्न बिट्स (वे सभी बाइट-संरेखित नहीं हैं) से मिलकर बनता है, और इसलिए जब आप उन्हें सांकेतिक शब्दों में बदलना या डिकोड करना चाहते हैं, तो उन्हें बिट-शिफ़्ट करने की आवश्यकता होती है ।
बिट शिफ्टिंग उच्च स्तरीय प्रोग्रामिंग समस्याओं को हल नहीं करता है, लेकिन बस हमें कभी-कभी निचले स्तर की समस्याओं को हल करना पड़ता है, और इसे करने के लिए C में एक अलग लाइब्रेरी लिखना सुविधाजनक नहीं है। जब यह सबसे अधिक इस्तेमाल किया जाता है तो मेरा अनुमान है।
मैंने व्यक्तिगत रूप से एक EBCDIC चरित्र सेट कनवर्टर के लिए एक एनकोडर लिखने में इसका उपयोग किया है ।
हाँ मेरे पास है। जैसा कि आपको संदेह है कि यह निम्न स्तर की प्रोग्रामिंग में पाया जा सकता है, उदाहरण के लिए उपकरणों के ड्राइवरों को विकसित करना। लेकिन, मैंने एक सी # परियोजना पर काम किया, जहां मुझे एक वेब सेवा विकसित करनी थी, जो चिकित्सा उपकरणों से डेटा प्राप्त करती थी। डिवाइस को संग्रहीत किए गए सभी बाइनरी डेटा को SOAP पैकेट में एन्कोड किया गया था, लेकिन बाइनरी डेटा को संकुचित और एन्कोड किया गया था। इसलिए इसे अनसुना करने के लिए, आपको बहुत सारे और बहुत सारे हेरफेर करने होंगे। और इसके अलावा आपको किसी भी उपयोगी जानकारी को पार्स करने के लिए बहुत सारे बिट शिफ्टिंग करने होंगे, उदाहरण के लिए डिवाइस सीरियल नंबर दूसरी बाइट का निचला आधा या ऐसा ही कुछ है। इसके अलावा, मैंने कुछ लोगों को .NET (C #) में देखा है जो बिट मास्किंग और फ्लैग एट्रीब्यूट का उपयोग करते हैं, मुझे व्यक्तिगत रूप से ऐसा करने का कभी आग्रह नहीं था।
जब छोटे एंडियन से बड़े एंडियन प्रारूप में संख्याओं को परिवर्तित करना और इसके विपरीत
बिट शिफ्टिंग का इस्तेमाल ऑनलाइन गेम्स के प्रोटोकॉल को दरकिनार करने में किया जाता है। प्रोटोकॉल संभव के रूप में थोड़ा बैंडविड्थ का उपयोग करने के लिए डिज़ाइन किए गए हैं, इसलिए एक सर्वर पर खिलाड़ियों की संख्या, नाम और इंट32s में आगे संचारित करने के बजाय, सभी जानकारी को संभव के रूप में कुछ बाइट्स में पैक किया गया है। ब्रॉडबैंड का उपयोग करने वाले अधिकांश लोगों के साथ यह वास्तव में इन दिनों आवश्यक नहीं है, लेकिन जब वे मूल रूप से डिज़ाइन किए गए लोग गेमिंग के लिए 56k मॉडेम का उपयोग करते थे, तो हर बिट गिना जाता था।
इसका सबसे प्रमुख उदाहरण वाल्व के मल्टीप्लेयर गेम्स में विशेष रूप से काउंटर-स्ट्राइक, काउंटर-स्ट्राइक स्रोत हैं। Quake3 प्रोटोकॉल भी समान है, हालांकि अवास्तविक स्लिमलाइन के रूप में काफी नहीं है।
यहाँ एक उदाहरण है (.NET 1.1)
string data = Encoding.Default.GetString(receive);
if ( data != "" )
{
// If first byte is 254 then we have multiple packets
if ( (byte) data[0] == 254 )
{
// High order contains count, low order index
packetCount = ((byte) data[8]) & 15; // indexed from 0
packetIndex = ((byte) data[8]) >> 4;
packetCount -= 1;
packets[packetIndex] = data.Remove(0,9);
}
else
{
packets[0] = data;
}
}
बेशक आप इसे एक वास्तविक परियोजना के रूप में देखते हैं या सिर्फ एक शौक (सी # में) आप पर निर्भर है।
फास्ट फूरियर ट्रांसफॉर्म - FFT और यह Cooley-Tukey तकनीक है जिसमें बिट शिफ्टिंग ऑपरेशन का उपयोग करना होगा।
मुझे डीवीडी डिस्क पर .ifo फ़ाइलों को पार्स करने के लिए एक कार्यक्रम लिखना था। ये दायरें हैं जो बताती हैं कि डिस्क पर कितने शीर्षक, अध्याय, मेनू आदि हैं। वे सभी आकारों और संरेखण के पैक बिट्स से बने होते हैं। मुझे संदेह है कि कई द्विआधारी प्रारूपों के लिए समान बिट शिफ्टिंग की आवश्यकता होती है।
मैंने बिटवाइज़ ऑपरेटरों का उपयोग तब देखा है जब एक संपत्ति पैरामीटर के रूप में कई झंडे का उपयोग किया गया था। उदाहरण के लिए संख्या 4 = 1 0 0 का अर्थ है कि तीन में से एक झंडे को सेट किया गया है। यह सार्वजनिक एपीआई के लिए अच्छा नहीं है, लेकिन यह विशेष मामलों में चीजों की गति बढ़ा सकता है क्योंकि बिट्स की जांच तेज है।
मेरे द्वारा लिखे गए हर बिटब्ल्ट-एर को बिट्स को बाएं और दाएं स्लाइड करने की क्षमता w / o पूरी नहीं हो सकती थी।
मैं एक एम्बेडेड सिस्टम के लिए एक परियोजना में इसका उपयोग करता हूं जिसे मॉनिटर के EDID डेटा को पढ़ना पड़ता है। EDID में कुछ डेटा इस तरह एन्कोड किया गया है:
बाइट # 3:
हॉरिज़ॉन्टल ब्लेंकिंग - लोअर 8 बिट्स
बाइट # 4:
लोअर निबल: हॉरिज़ॉन्टल ब्लैंकिंग - अपर 4 बिट्स
अपर निबेल: कुछ और
हां, जब जावा और सी # अनुप्रयोगों के बीच द्विआधारी संचार करते हैं, तो एक बड़ा-एंडियन बाइट ऑर्डर करता है और दूसरा थोड़ा-एंडियन (इस आदेश पर जरूरी नहीं) है। मैंने एक InputStream क्लास बनाई, जो एक अलग बाइट ऑर्डर के साथ नंबर पढ़ सकती थी, और यह काम करने के लिए बाइट-शिफ्टिंग का इस्तेमाल करती थी।
कभी-कभी जब आप एक लंबे समय के 4 बाइट्स में 4 शॉर्ट्स डालना चाहते हैं, तो यह बाइट शिफ्टिंग का उपयोग करने के मामले में होगा। मुझे लगता है कि मैंने कई साल पहले किया था ...
एक और बहुत ही सामान्य बात यह है कि एक बाइट के उच्च निबल को निकालने पर 4 बिट शिफ्ट करना है , अर्थात
#define HIGH_NIBBLE(byte) (((byte) >> 4) & 0x0F)
#define LOW_NIBBLE(byte) ( (byte) & 0x0F)
हां, हर समय निम्न स्तर के एम्बेडेड सॉफ़्टवेयर में बिट शिफ्टिंग का उपयोग किया जा रहा है। यह भी तेजी से गणित संचालन करने के लिए एक लगभग जादू की चाल के रूप में इस्तेमाल किया जा सकता है, एक नज़र है
http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/
हाँ हर समय। एक 32-बिट पूर्णांक से / के लिए 3 क्षेत्र समन्वय और पैकिंग के लिए इन मैक्रो की तरह:
#define Top_Code(a, b, c) ((((a) + x) << 20) | (((b) + y) << 10) | ((c) + z))
#define From_Top_Code(a, b, c, f) (a = (((f) >>> 20) - x), b = ((((f) & 0xffc00) >>> 10) - y), c = (((f) & 0x3ff) - z))
मैंने एक बार (कई, कई साल पहले) एक प्रोजेक्ट के लिए आउटपुट रूटीन लिखा था जिसने एक्सेल ऑपरेशन संरचना का उपयोग करके एक्सेल स्प्रेडशीट बनाया। यह एक बाइनरी फाइल फॉर्मेंट था जिसमें बड़ी मात्रा में बिट ट्विडलिंग की आवश्यकता होती थी। निम्न लिंक ऑपरेशन संरचना सफारी बुक्स का स्वाद देता है ।