एक बूलियन 1 बाइट और 1 बिट आकार क्यों नहीं है?


127

C ++ में,

  • एक बूलियन 1 बाइट और 1 बिट आकार क्यों नहीं है?
  • 4-बिट या 2-बिट पूर्णांक की तरह क्यों नहीं हैं?

CPU के लिए एमुलेटर लिखते समय मुझे उपरोक्त बातें याद आ रही हैं


10
C ++ में आप बिट-फ़ील्ड का उपयोग करके डेटा को "पैक" कर सकते हैं। struct Packed { unsigned int flag1 : 1; unsigned int flag2: 1; };। अधिकांश संकलक एक पूर्ण आवंटित करेंगे unsigned int, हालांकि जब आप पढ़ते / लिखते हैं तो वे खुद से बिट-ट्विडलिंग से निपटते हैं। इसके अलावा वे खुद के साथ काम करते हैं modulo संचालन। यह एक unsigned small : 4विशेषता है 0 और 15 के बीच एक मान है, और जब यह 16 को मिलना चाहिए, तो यह पूर्ववर्ती बिट को अधिलेखित नहीं करेगा :)
Matthieu M.

जवाबों:


208

क्योंकि सीपीयू किसी बाइट से छोटे को संबोधित नहीं कर सकता है।


10
अरे, अब है कि अजीब सर है
Asm

31
वास्तव में, चार 86 निर्देश bt, bts, btrऔर btc कर सकते हैं एक बिट को संबोधित!
16:30 पर fredoverflow

11
मुझे लगता है कि btएक बाइट ऑफसेट को संबोधित करता है और फिर किसी दिए गए ऑफसेट पर बिट का परीक्षण करता है, फिर भी, जब आप एक पते को बाइट्स में निर्दिष्ट करते हैं, तो निर्दिष्ट करें ... बिट ऑफ़सेट शाब्दिकों को थोड़ा वर्डी मिलेगा ( दण्ड का बहाना)।
user7116

2
@ सिक्स: आप एक रजिस्टर में एक सरणी की शुरुआत को लोड कर सकते हैं और फिर दूसरे में रिश्तेदार "बिट ऑफ़सेट"। बिट ऑफ़सेट "एक बाइट के भीतर" तक सीमित नहीं है, यह किसी भी 32 बिट संख्या हो सकती है।
फ्रेडओवरफ्लो

4
खैर, हाँ और नहीं। हमारे पास बिटफ़िल्ड है, और हमारे पास बिटफ़ील्ड पॉइंटर हो सकता है, जो एड्रेस + बिट नंबर है। जाहिर है, इस तरह के सूचक बिट संख्या के लिए अतिरिक्त भंडारण की आवश्यकता के कारण शून्य * के लिए परिवर्तनीय नहीं होंगे।
मैक्सिम Egorushkin

32

से विकिपीडिया :

ऐतिहासिक रूप से, एक बाइट एक कंप्यूटर में पाठ के एकल वर्ण को एन्कोड करने के लिए उपयोग की जाने वाली बिट्स की संख्या थी और यह इस कारण से कई कंप्यूटर आर्किटेक्चर में मूल पता योग्य तत्व है।

तो बाइट है बुनियादी पता इकाई है, जो नीचे कंप्यूटर वास्तुकला का पता नहीं कर सकते। और चूंकि वहाँ (शायद) ऐसे कंप्यूटर मौजूद नहीं हैं जो 4-बिट बाइट का समर्थन करते हैं, आपके पास 4-बिट आदि नहीं हैं । bool

हालाँकि, यदि आप ऐसे आर्किटेक्चर को डिज़ाइन कर सकते हैं जो 4-बिट को मूल पते योग्य इकाई के रूप में संबोधित कर सकता है, तो आपके पास boolआकार 4-बिट का होगा, केवल उस कंप्यूटर पर!


4
"आपके पास आकार केवल 4-बिट का होगा, फिर उस कंप्यूटर पर" - नहीं आप नहीं करेंगे, क्योंकि मानक CHAR_BIT से कम होने से मना करता है। 8. यदि आर्किटेक्चर पर पता करने योग्य इकाई 8 बिट से कम है, तो ए। C ++ कार्यान्वयन में बस एक मेमोरी मॉडल प्रस्तुत करना होगा जो अंतर्निहित हार्डवेयर के मेमोरी मॉडल से अलग है।
स्टीव जेसोप

@Steve: उफ़ ... मैंने इस बात को नज़रअंदाज़ कर दिया। निकाला गया intऔर charमेरी पोस्ट से।
नवाज

1
आपके पास 4-बिट boolभी नहीं हो सकता है , क्योंकि charसबसे छोटी पता योग्य इकाई है C ++ में है , चाहे आर्किटेक्चर अपने स्वयं के ऑपकोड के साथ पता कर सकता है। sizeof(bool)कम से कम 1 का मान होना चाहिए, और आस-पास की boolवस्तुओं का C ++ में अपना पता होना चाहिए , इसलिए कार्यान्वयन को बस उन्हें बड़ा और बेकार स्मृति बनाना है। यही कारण है कि बिट फ़ील्ड एक विशेष मामले के रूप में मौजूद हैं: किसी संरचना के बिटफील्ड सदस्यों को अलग से पता करने की आवश्यकता नहीं होती है, इसलिए वे एक से छोटे हो सकते हैं char(हालांकि पूरी संरचना अभी भी नहीं हो सकती है)।
स्टीव जेसोप

@ स्टीव जेसोप: यह दिलचस्प लगता है। क्या आप मुझे भाषा विनिर्देश से संदर्भ दे सकते हैं, जहां यह कहता charहै कि C ++ में सबसे छोटी पता योग्य इकाई है?
नवाज

3
निकटतम विशिष्ट कथन शायद ३.९ / ४ है: "टाइप टी के ऑब्जेक्ट का ऑब्जेक्ट प्रतिनिधित्व एन टाइप के ऑब्जेक्ट द्वारा उठाए गए एन अहस्ताक्षरित चार ऑब्जेक्ट्स का अनुक्रम है, जहां एन आकार आकार (टी) के बराबर है।" स्पष्ट रूप sizeof(bool)से 0.5 नहीं हो सकता है :-) मुझे लगता है कि एक कार्यान्वयन कानूनी तौर पर उप-बाइट पॉइंटर्स को एक विस्तार के रूप में प्रदान कर सकता है, लेकिन "साधारण" ऑब्जेक्ट्स जैसे कि बूल, सामान्य तरीके से आवंटित किए गए हैं, उन्हें वही करना होगा जो मानक कहते हैं।
स्टीव जेसोप

12

सबसे आसान जवाब है; यह इसलिए है क्योंकि सीपीयू बाइट्स में मेमोरी को संबोधित करता है और बिट्स में नहीं, और बिटवाइज़ ऑपरेशन बहुत धीमा है।

हालाँकि C ++ में बिट-साइज़ आवंटन का उपयोग करना संभव है। एसटीडी :: बिट वैक्टर के लिए वेक्टर विशेषज्ञता, और बिट आकार की प्रविष्टियां लेने वाली संरचनाएं भी हैं।


1
मुझे यकीन नहीं है कि मैं सहमत हूँ कि बिटवाइज़ ऑपरेशन धीमा है ands, nots, xors आदि बहुत तेज हैं। यह आमतौर पर धीमे चलने वाले बिटवाइज़ ऑपरेशंस का कार्यान्वयन है। मशीन के स्तर पर वे काफी तेज हैं। शाखाओं में बंटी ... अब वह धीमी है।
होगन

3
बस इसे और अधिक स्पष्ट करने के लिए, यदि आप बूलियन का वेक्टर बनाते हैं और इसमें 24 बूलियन डालते हैं, तो यह केवल 3 बाइट्स ले रहा होगा (3 * 8)। यदि आप एक और बूलियन में डालते हैं, तो यह एक और बाइट लेगा। फिर भी, यदि आप एक और बूलियन को धक्का देते हैं, तो यह किसी भी अतिरिक्त बाइट को नहीं लेगा क्योंकि यह अंतिम बाइट में "फ्री" बिट्स का उपयोग करता है
पेड्रो लौरेइरो

हाँ, मुझे यह भी संदेह है कि बिटवाइस के संचालन की गति धीमी है :)
पेड्रो

बिट वैक्टर बिट आकार के आवंटन नहीं बनाते हैं। वे बाइट के आकार के आवंटन बनाते हैं। एक बिट आवंटित करना संभव नहीं है।
जॉन डिब्लिंग

1
एक बिट वेक्टर में एक बिट पढ़ने के लिए तीन ऑपरेशनों की आवश्यकता होती है: शिफ्ट, और दूसरी शिफ्ट। लेखन दो है। जबकि व्यक्तिगत बाइट्स को एकल के साथ एक्सेस किया जा सकता है।
सूक्रू su

7

पुराने दिनों में वापस जब मुझे स्कूल जाने के लिए तेजस्वी बर्फ़ीला तूफ़ान, दोनों तरह से ऊपर उठना पड़ता था, और दोपहर का भोजन जो भी जानवर हम स्कूल के पीछे जंगल में ट्रैक कर सकते थे और अपने नंगे हाथों से मार सकते थे, कंप्यूटर की तुलना में बहुत कम स्मृति उपलब्ध थी आज। पहला कंप्यूटर जो मैंने कभी इस्तेमाल किया था उसमें 6K RAM था। 6 मेगाबाइट नहीं, 6 गीगाबाइट नहीं, 6 किलोबाइट। उस वातावरण में, आपने बहुत से बूलियनों को इंट के रूप में पैक करने के लिए बहुत समझदारी की है और इसलिए हम नियमित रूप से उन्हें बाहर निकालने और अंदर डालने के लिए ऑपरेशन का उपयोग करेंगे।

आज, जब लोग आपको केवल 1 जीबी रैम होने के लिए मजाक करेंगे, और एकमात्र जगह जिसे आप 200 जीबी से कम के साथ एक हार्ड ड्राइव पा सकते हैं, एक प्राचीन दुकान पर है, यह सिर्फ बिट्स को पैक करने की परेशानी के लायक नहीं है।


सिवाय जब झंडे से निपटने के। किसी चीज़ पर कई विकल्प सेट करने जैसी चीजें ... जैसे। 00000001 + 00000100 = 00000101.
आर्मस्ट्रांगस्ट

@Atomix: मैं लगभग अब ऐसा कभी नहीं करता। अगर मुझे दो झंडे चाहिए, तो मैं दो बूलियन फ़ील्ड बनाता हूं। मैं कोड लिखता था जहाँ मैं उस तरह के झंडे लगाता था और फिर लिखता था "अगर झंडे और 0x110! = 0 तब" या पसंद है, लेकिन यह गुप्त है और इन दिनों मैं आम तौर पर अलग-अलग फ़ील्ड बनाता हूँ और लिखता हूँ "अगर fooFlag || barFagag " बजाय। मैं उन मामलों की संभावना को खारिज नहीं करूंगा जहां झंडे को पैक करना किसी कारण से बेहतर है, लेकिन यह अब मेमोरी को बचाने के लिए आवश्यक नहीं है जैसे कि यह हुआ करता था।
जे

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

2
सचमुच बड़ी संख्या में बूलियन्स हैं जो आप हर दिन काम करते हैं यदि आप करते हैं: DBMSes, मशीन लर्निंग, वैज्ञानिक सिमुलेशन, और अन्य चीजों की एक पूरी मेजबानी। और - बस उन पर काम करने का मतलब है उन्हें कॉपी करना - मेमोरी से कैश में। एक लाख बूल कुछ भी नहीं है, अरबों सोचो।
ईनपोकलुम

1
@PeterCordes हाँ, बिलकुल, अगर मेरे पास बूलियनों का एक सेट था जो तार्किक रूप से "एक ही विचार" था ताकि मैं स्वाभाविक रूप से उन्हें कुछ अर्थों में "सरणी" के रूप में सोचूं, और अगर मैं तब उन्हें मुखौटा या फ़िल्टर करने जा रहा हूं या अन्यथा उन पर बिटवाइज़ ऑपरेशन करें, फिर उन्हें बाइट में पैक करने से अच्छी समझ आ सकती है। जैसा कि मैंने पहले कहा था, मुझे लगता है कि पिछली बार मैंने एक आवेदन पर काम किया है, जहां उन शर्तों को लागू करने के बारे में सोचने के लिए मुझे दबाया गया है, लेकिन आप कुछ अच्छे उदाहरण देते हैं, और मुझे यकीन है कि थोड़ी कल्पना के साथ दूसरों के बारे में सोच सकते हैं।
जय

6

आपके पास 1-बिट बूल और 4 और 2-बिट इनट्स हो सकते हैं। लेकिन यह बिना किसी प्रदर्शन के लाभ के लिए एक अजीब निर्देश सेट होगा क्योंकि यह वास्तुकला को देखने के लिए एक अप्राकृतिक तरीका है। यह वास्तव में उस अप्रयुक्त डेटा को पुनः प्राप्त करने की कोशिश करने के बजाय एक बाइट का एक बेहतर हिस्सा "बेकार" करने के लिए समझ में आता है।

एकमात्र ऐप जो मेरे अनुभव में, एक ही बाइट में कई बूल पैक करने के लिए परेशान करता है, वह है Sql Server।


5

सब-साइज़ के पूर्णांक प्राप्त करने के लिए आप बिट फ़ील्ड का उपयोग कर सकते हैं।

struct X
{
    int   val:4;   // 4 bit int.
};

हालांकि इसका उपयोग आमतौर पर संरचनाओं को सटीक हार्डवेयर अपेक्षित बिट पैटर्न में मैप करने के लिए किया जाता है:

struct SomThing   // 1 byte value (on a system where 8 bits is a byte
{
    int   p1:4;   // 4 bit field
    int   p2:3;   // 3 bit field
    int   p3:1;   // 1 bit
};

5

क्योंकि एक बाइट भाषा की सबसे छोटी पता योग्य इकाई है।

लेकिन अगर आप उनमें से एक गुच्छा है जैसे उदाहरण के लिए आप बूल ले सकते हैं 1 बिट। एक संरचना में, इस तरह:

struct A
{
  bool a:1, b:1, c:1, d:1, e:1;
};

2

boolएक बाइट हो सकता है - सीपीयू का सबसे छोटा पता योग्य आकार, या बड़ा हो सकता है। प्रदर्शन उद्देश्यों boolके intलिए इसका आकार होना असामान्य नहीं है। यदि विशिष्ट उद्देश्यों के लिए (हार्डवेयर सिमुलेशन कहते हैं) आपको एन बिट्स के साथ एक प्रकार की आवश्यकता है, तो आप उसके लिए एक पुस्तकालय पा सकते हैं (जैसे जीबीएल पुस्तकालय में BitSet<N>कक्षा है)। यदि आप आकार से चिंतित हैं bool(आपके पास शायद एक बड़ा कंटेनर है), तो आप अपने आप को बिट्स पैक कर सकते हैं, या इसका उपयोग कर सकते हैं std::vector<bool>जो आपके लिए करेगा (बाद वाले से सावधान रहें, क्योंकि यह कंटेनर की आवश्यकता को पूरा नहीं करता है)।


2

इस बारे में सोचें कि आप इसे अपने एमुलेटर स्तर पर कैसे लागू करेंगे ...

bool a[10] = {false};

bool &rbool = a[3];
bool *pbool = a + 3;

assert(pbool == &rbool);
rbool = true;
assert(*pbool);
*pbool = false;
assert(!rbool);

2

क्योंकि सामान्य तौर पर, CPU मूल इकाई के रूप में 1 बाइट के साथ मेमोरी आवंटित करता है, हालांकि कुछ CPU जैसे MIPS में 4-बाइट शब्द का उपयोग किया जाता है।

हालांकि एक विशेष फैशन में vectorसौदों bool, vector<bool>प्रत्येक बूल के लिए एक बिट आवंटित किया जाता है।


1
मेरा मानना ​​है कि यहां तक ​​कि MIPS cpu आपको एक व्यक्तिगत बाइट तक पहुंच प्रदान करेगा, हालांकि एक प्रदर्शन जुर्माना है।
पॉल टॉम्बलिन

@Paul: हाँ आप सही हैं, लेकिन आम तौर पर शब्द-विशिष्ट lw/ swबहुत अधिक व्यापक रूप से उपयोग किए जाते हैं।
रयान ली

MIPS के बारे में नहीं जानते, लेकिन IA-64 आर्किटेक्चर केवल 64-बिट सीमा पर ही पहुँच प्रदान करता है।
जीन बुशुइव

0

बाइट कंप्यूटर की डिजिटल डेटा स्टोरेज की छोटी इकाई है। एक कंप्यूटर में RAM में लाखों बाइट्स हैं और उनमें से किसी का भी पता है। अगर यह हर बिट के लिए एक पता होता है तो एक कंप्यूटर 8 बार कम रैम का प्रबंधन कर सकता है कि यह क्या कर सकता है।

अधिक जानकारी: विकिपीडिया


0

यहां तक ​​कि जब न्यूनतम संभव आकार 1 बाइट है, तो आपके पास 1 बाइट पर बूलियन जानकारी के 8 बिट्स हो सकते हैं:

http://en.wikipedia.org/wiki/Bit_array

जूलिया भाषा में उदाहरण के लिए BitArray है, और मैं C ++ कार्यान्वयन के बारे में पढ़ता हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.