कई बूलियन राज्यों को एक संख्या में संग्रहीत / पैकिंग करने के लिए क्या नाम है?


55

यह एक प्रकार का सरल संपीड़न है जहां आप एक बूलियन / बाइनरी राज्यों को संग्रहीत करने के लिए एक संख्यात्मक चर का उपयोग करते हैं, दोहरीकरण और इस तथ्य का उपयोग करते हैं कि प्रत्येक दोहरीकरण संख्या 1 + सभी पिछले वाले का योग है।

मुझे यकीन है कि यह एक पुरानी, ​​प्रसिद्ध तकनीक होनी चाहिए, मैं जानना चाहता हूं कि इसे ठीक से संदर्भित करने के लिए क्या कहा जाता है। मैंने हर तरह से कई खोजों को किया है जो मैं इसका वर्णन करने के बारे में सोच सकता हूं, लेकिन कुछ ब्लॉग लेखों से परे कुछ भी नहीं मिला जहां लेख लेखकों ने खुद को यह पता लगाया है और यह नहीं जानते कि इसे क्या कहा जाए, या तो ( उदाहरण 1 ) उदाहरण 2 )।

उदाहरण के लिए, यहाँ एक बहुत ही सरल कार्यान्वयन अवधारणा का वर्णन करने का इरादा है:

packStatesIntoNumber () {
  let num = 0
  if (this.stateA) num += 1
  if (this.stateB) num += 2
  if (this.stateC) num += 4
  if (this.stateD) num += 8
  if (this.stateE) num += 16
  if (this.stateF) num += 32
  return num
}

unpackStatesFromNumber (num) {
  assert(num < 64)
  this.stateF = num >= 32; if (this.stateF) num -= 32
  this.stateE = num >= 16; if (this.stateE) num -= 16
  this.stateD = num >= 8; if (this.stateD) num -= 8
  this.stateC = num >= 4; if (this.stateC) num -= 4
  this.stateB = num >= 2; if (this.stateB) num -= 2
  this.stateA = num >= 1; if (this.stateA) num -= 1
}

आप बिटवाइज़ ऑपरेटर्स, बेस 2 नंबर पार्सिंग, एनम का भी उपयोग कर सकते हैं ... इसे लागू करने के कई और अधिक कुशल तरीके हैं, मैं दृष्टिकोण के नाम पर आम तौर पर दिलचस्पी रखता हूं।


8
C # में, हैं enums, और उनके पास एक Flagsविशेषता हो सकती है । वे आपके कोड को अधिक सरल बना सकते हैं।
बर्नहार्ड हिलर

12
मैं इसे "बिट फ़ील्ड्स का अनुकरण" कहूंगा। यह लगभग हमेशा एक बुरा विचार है जब तक कि अंतरिक्ष दक्षता अत्यधिक महत्वपूर्ण नहीं है।
किलन फ़ॉथ

7
@KilianFoth A boolको आमतौर पर आंतरिक रूप से 32 बिट पूर्णांक के रूप में संग्रहीत किया जाता है। जैसे, पैकिंग 32 के एक कारक का अंतर बना सकती है। यह वास्तव में बहुत कुछ है। मेरा मतलब है, हम प्रोग्रामर हमेशा अपने आधे संसाधनों को फेंकने के लिए तैयार हैं, लेकिन मैं उनमें से 97% को फेंकने के लिए आम तौर पर अनिच्छुक हूं। इस तरह के अपशिष्ट कारक आसानी से महत्वपूर्ण उपयोग के मामलों को चलाने और स्मृति से बाहर चलाने के बीच अंतर कर सकते हैं।
सेमीस्टर

3
ऐतिहासिक रूप से, आमतौर पर बिट मास्क का उपयोग मूल्यों को घोषित करने, सेट करने और पुनः प्राप्त करने के लिए किया जाता है। पारियों का उपयोग करना अजीब है और वास्तव में दृष्टिकोण का सबसे अच्छा चित्रण नहीं है।
जिमीजैम

3
@cmaster कारण बूल उस तरह से संग्रहीत होते हैं क्योंकि एक ही मेमोरी लोकेशन (आज की मशीनों पर 32 या 64 बिट्स) साझा करना कैश के प्रदर्शन के लिए बहुत बुरा हो सकता है जब तक आप मशीन भाषा कोड पर बहुत ध्यान नहीं देते। यदि आपके पास वास्तव में बड़े पैमाने पर बिट्स हैं, तो यह संभवतः इसके लायक है, लेकिन यदि आप संभवतः पूर्व-अनुकूलन से बेहतर नहीं हैं और बिट्स को पैक कर रहे हैं जब आप नेटवर्क या डिस्क पर संचारित होने के लिए तैयार हैं।
बिल के

जवाबों:


107

इसे आमतौर पर एक बिट फ़ील्ड के रूप में संदर्भित किया जाता है , और दूसरा शब्द जो आप अक्सर सुनते हैं वह बिट मास्क होता है , जो एक ही बार में पूरे बिट फ़ील्ड या संपूर्ण बिट फ़ील्ड को प्राप्त करने या सेट करने के लिए उपयोग किया जाता है।

कई प्रोग्रामिंग भाषाओं में इसके साथ मदद करने के लिए सहायक संरचनाएं हैं। टिप्पणियों में @BernhardHiller नोट के रूप में, C # में झंडे के साथ दुश्मनी है ; जावा में EnumSet क्लास है।


4
मैं "बिट फ़ील्ड" को एक भाषा सुविधा का उपयोग करने के रूप में व्याख्या करूंगा जो व्यक्तिगत बिट्स को एक फ्रेमवर्क के क्षेत्रों में निर्दिष्ट करने की अनुमति देता है बजाय इसे मैन्युअल रूप से बुद्धिमान ऑपरेटरों के साथ।
पीटर ग्रीन

22
@PeterGreen मानक व्याख्या से अलग होगा।
एरिक

1
"बिट मैपिंग" या "बिट मैप्ड", सामान्य रिकॉर्ड्स और सरणी प्रसंस्करण के लिए सामान्य, इस मामले में भी लागू हो सकते हैं। कई सेटों से आम तत्वों को निकालते समय एक संघटित मॉडल के घटकों की पहचान करने के लिए मूल्य को विघटित किया जा सकता है। यहाँ तक कि हम इसे अष्टक फ़िल्मी अंको का भी कहते हैं। बिट मास्क (कोई भी मास्क) फिल्टर होते हैं (जैसे कि आईओ पोर्ट और डेटा दिशा रजिस्टर के लिए)।
मैकेंज़्म

1
सी # भी है BitArray, जो बिट्स की एक मनमानी राशि को संग्रहीत करने और उन्हें अनुक्रमित करने की अनुमति देता है (जबकि झंडे एक पूर्णांक प्रकार तक सीमित हैं और मास्क के रूप में उपयोग किए जाने का इरादा है)।
लुआं

सच; मैंने सिर्फ उन दो संरचनाओं का उल्लेख किया है जिनसे मैं सबसे अधिक परिचित हूं। वहाँ शायद दर्जनों हैं, खासकर अन्य भाषाओं में।
ग्लोरफाइंडेल

20

अजीब बात है, यहाँ काफी अलग-अलग शब्द हैं, लेकिन मुझे वह नहीं दिखता है जो तुरंत दिमाग में आया (और यह आपके प्रश्न के शीर्षक में है!) - बिट पैकिंग वह है जो मैंने हमेशा सुना है जिसे यह कहा जाता है।

मैंने सोचा था कि यह वास्तव में स्पष्ट था, लेकिन अजीब है कि जब मैं Google करता हूं तो ऐसा लगता है कि यह एक शब्द है जिसका व्यापक रूप से उपयोग किया जाता है, लेकिन आधिकारिक तौर पर परिभाषित नहीं किया गया है (विकिपीडिया बिट क्षेत्र में पुनर्निर्देशित करता है जो कि बिट पैकिंग करने का एक तरीका है, लेकिन एक नाम के लिए नहीं। प्रक्रिया)। इस पृष्ठ पर ले जाने के लिए परिभाषा खोज रहा है:

http://www.kinematicsoup.com/news/2016/9/6/data-compression-bit-packing-101

जो SO प्रयोजनों के लिए बहुत अच्छा नहीं है, लेकिन यह सबसे अच्छी परिभाषा / विवरण है जो मैं इस संक्षिप्त विवरण सहित पा सकता हूं: "बिट-पैकिंग एक सरल अवधारणा है: डेटा का एक टुकड़ा स्टोर करने के लिए जितना संभव हो उतना कम उपयोग करें।"


क्या आप कुछ संदर्भ प्रदान कर सकते हैं? दिलचस्प शब्द है।
ग्रेग बरगार्ड

13
बिट पैकिंग तकनीकी रूप से सही है, लेकिन बूलियन राज्यों की तुलना में अधिक सामान्य बात को संदर्भित करता है - संभव के रूप में बिट्स की सबसे छोटी संख्या में सामान्य रूप से डेटा संग्रहीत करना। उदाहरण के लिए, इसका एक और उपयोग charदो charएस को एक में रखकर एक सरणी को संपीड़ित करने का मतलब हो सकता है int
इजाकाता

@GregBurghardt आप जानते हैं, यह दिलचस्प है। जब मैंने पोस्ट किया तो मैं इसके बारे में नहीं सोचता था क्योंकि यह शब्द 80/90 के दशक में बहुत प्रचलित था जब मैंने C और असेंबली में प्रोग्रामिंग सीखी थी - अब हालांकि एक Google खोज में कई उल्लेख मिलते हैं, इसके लिए कोई निश्चित विकिपीडिया पृष्ठ नहीं है । Google में पहले उत्तर में यह परिभाषा है: "बिट-पैकिंग एक सरल अवधारणा है: डेटा का एक टुकड़ा स्टोर करने के लिए जितना संभव हो उतना कम उपयोग करें।" kinematicsoup.com/news/2016/9/6/…
बिल के

जब मैंने बिट पैकिंग के बारे में भी सीखा है, हालांकि आप अप्रयुक्त 0 को पुन: उपयोग करने की तुलना में बहुत अधिक क्रैजियर प्राप्त कर सकते हैं जो कि मुख्य रूप से पूर्णांक मान होंगे। कुछ साल पहले मैं एक ऐसे सिस्टम में भाग गया, जिसने अपने मापदंडों में से एक को 8 बिट फ्लोट के रूप में संग्रहीत किया। एक अहस्ताक्षरित mantissa के लिए IIRC 5 बिट्स (सभी मान सकारात्मक थे साइन को स्पष्ट रूप से संग्रहीत करने की कोई आवश्यकता नहीं थी), और आधार 10 एक्सपोर्टर के लिए 3 अधिक। उस समय मैंने मान लिया था कि यह एक विरासत हार्डवेयर कीचड़ है जिसके आगे कोई रास्ता नहीं है, लेकिन मशीन सीखने के साथ हाल ही में int4 बनाम int8 के साथ सामान बनाना शुरू किया, मैं देख सकता था कि कुछ वर्कलोड FP16 से नीचे गिर रहे हैं।
डैन नीली

1
@DanNeely इस तरह की बात को आमतौर पर GPU द्वारा भी समर्थन किया जाता है - सटीक, मेमोरी और कम्प्यूटेशन के बीच व्यापार करना बहुत महत्वपूर्ण है। जीपीयू-आधारित कंप्यूटिंग के साथ यह बहुत अच्छा शोषण किया गया है।
लुआं

14

इसका वर्णन करने के लिए उपयोग किए जाने वाले कई अलग-अलग शब्द हैं।

आमतौर पर बिट्स को "बिट फ्लैग" या "बिट फ़ील्ड" कहा जाता है।
(हालांकि, यह ध्यान देने योग्य है कि "बिट फ़ील्ड" कभी-कभी सी और सी ++ भाषाओं की एक विशिष्ट विशेषता को संदर्भित करता है, जो संबंधित है लेकिन बिल्कुल समान नहीं है।)

पूर्णांक स्वयं को एक "बिट एरे", एक "बिट सेट" या एक "बिट वेक्टर" के रूप में विभिन्न रूप से संदर्भित किया जाता है, जो usages और परिस्थितियों पर निर्भर करता है।

किसी भी तरह से, बिट सेट / वेक्टर / सरणी से बिट्स को स्थानांतरित करने और मास्किंग के माध्यम से किया जाता है।
(यानी थोड़ा सा मास्क का उपयोग करके ।)


सक्रिय उपयोग में प्रत्येक पद के कुछ उदाहरणों के लिए:

  • इस विषय पर विकिपीडिया के लेख का शीर्षक बिट सरणी है , जो नोट करता है कि "इसे बिट मैप, बिट सेट, बिट स्ट्रिंग या बिट वेक्टर के रूप में भी जाना जाता है"
  • C ++ का उपयोग करता है std::bitset
  • जावा का उपयोग करता है BitSet
  • सी # का उपयोग करता है BitArray
  • StackOverflow के टैग हैं bitvector, bitarrayऔरbitset
  • PyPi पर एक bitarrayपरियोजना और एक BitVectorपरियोजना है

यह वास्तव में सवाल के अनुकूल नहीं है, लेकिन मैं यह कहना चाहूंगा: कृपया बिट्स को जोड़ने और घटाने के लिए उपयोग न करें और बिट्स को साफ करें क्योंकि उन तरीकों में त्रुटि होने का खतरा है।
(यानी यदि आप num += 1दो बार करते हैं , तो परिणाम बराबर होता है num += 2।)

यदि आपकी चुनी हुई भाषा उन्हें प्रदान करती है, तो इसके बजाय उचित बिटवाइज़ ऑपरेशंस का उपयोग करना पसंद करें:

packStatesIntoNumber ()
{
  let num = 0
  if (this.stateA) num |= 1
  if (this.stateB) num |= 2
  if (this.stateC) num |= 4
  if (this.stateD) num |= 8
  if (this.stateE) num |= 16
  if (this.stateF) num |= 32
  return num
}

unpackStatesFromNumber (num)
{
  this.stateF = ((num & 32) != 0);
  this.stateE = ((num & 16) != 0);
  this.stateD = ((num & 8) != 0);
  this.stateC = ((num & 4) != 0);
  this.stateB = ((num & 2) != 0);
  this.stateA = ((num & 1) != 0);
}

1
this.stateF = (num & 32) ? true : false, आदि numजब आप मूल्यों को निकाल रहे हैं, तो म्यूट करने की कोई आवश्यकता नहीं है ।
रोजर लिप्सकॉम्ब

3
अच्छा बिंदु @RogerLipscombe, मैं सच में, क्या कोड के माध्यम से कर रहा था पढ़ नहीं था बस के उपयोग के लिए प्रतिक्रिया +और -। मैं अब एक बेहतर और != 0एक टर्नरी के बजाय इस्तेमाल किया है , जो मुझे लगता है कि अधिक संक्षिप्त है जबकि अभी भी निष्कासित किया जा रहा है।
छत्र
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.