Come funziona la memorizzazione delle informazioni bit a bit nelle variabili int (32 bit)?

4

In questo libro sto leggendo sto esaminando operatori bit a bit. La sua dice quanto segue nel libro.

Bitwise operations can potentially store a lot of information in a small amount of memory. Many traits in the world have only two possibilities that are either this way or that way. You are either married or you're not. you are either male or female. In C++, you can store each of these traits in a single bit. This way you can pack 32 separte binary properties into a single 32-bit int.

Quindi è quello che dice quando usi gli operatori bit a bit in C ++ costerebbe solo 1 bit di memoria? Non sono sicuro di cosa sia rilevante la cosa int a 32 bit e anche quando parla di "memoria" è questa la RAM che il programma occupa? Perché quando eseguo i miei programmi C ++ sono molto al di sopra di 1 bit di RAM che viene eseguito l'ocuping. Sto guardando questo nel modo sbagliato?

    
posta 99Con 21.07.2016 - 16:50
fonte

5 risposte

15

Il libro parla di ciò che è comunemente noto come bitfield, e il loro uso è spesso più efficiente in termini di memoria sulla maggior parte delle piattaforme, specialmente in contesti di serializzazione o comunicazione. Un booleano richiede che il proprio indirizzo sia utilizzabile dal compilatore. Ciò significa che, mentre, praticamente, abbiamo solo bisogno di un bit per rappresentare una condizione vera (1) o falsa (0), non esiste un modo fisico per indirizzare e memorizzare un bit in memoria. Questo spesso significa che un booleano occuperà un intero byte in memoria, proprio come il più piccolo intero su quella stessa piattaforma.

Ora diciamo che hai 18 variabili booleane. Ognuno avrà bisogno di un suo pezzo di memoria indirizzata in modo tale da poterlo fare riferimento altrove nel software. Ciò significa che nel nostro sistema teorico abbiamo bisogno di 18 byte. La gente ha iniziato a vedere questo come uno spreco di memoria, in quanto solo un bit di ogni byte era davvero necessario.

Inserisci bitfield. Se guardiamo un numero intero che corrisponde alla dimensione della memoria indirizzabile del sistema, vediamo che occupa lo stesso numero di bit di un singolo booleano. Gli integer utilizzano tutti i bit per rappresentare il suo intervallo di valori. (Il valore decimale 26 è rappresentato come 00000000 00000000 00000000 00011010 su un sistema a 32 bit, 3572 è 00000000 00000000 00001101 11110100, ecc.).

Gli operatori bit a bit ci permettono di giocare direttamente con quei bit, piuttosto che doversi preoccupare di qualsiasi valore intero reale che essi intendevano rappresentare. Questo è importante, perché se assegni dei significati in anticipo a ciascuno di questi bit, puoi impostarli su 1 e 0 in modo esplicito e trattare ciascun bit singolarmente come booleano.

Le persone amano stravolgere le analogie, ma ho intenzione di dargli uno scatto comunque:

Pensa a una strada di case in una zona ricca di scapoli. Ogni casa ha un indirizzo sulla strada, e ogni casa ha 32 stanze, ma solo una persona vive in ogni casa. Gli scapoli sono i nostri booleani. Ora diciamo che una famiglia si trasferisce in una delle case. Sono considerati una famiglia, ma ora ci sono molte più persone che vivono nella casa. Questo è come il nostro intero - mentre più persone ora occupano le stanze, lo vediamo ancora come una casa con un solo valore (la famiglia che vive lì). Ora un'altra casa viene convertita in appartamenti. Mentre fisicamente continua a occupare solo una casa per strada, assegniamo alcune lettere ad ogni stanza (Appartamento 1A, appartamento 2C, ecc.) Che non influenzano l'indirizzo fisico o la composizione della casa, ma facciamo riferimento a ciascuna persona individualmente - Questo è il campo di bit.

In pratica, considererei l'uso dei bitfield prima invece dei booleans come caso di pre-ottimizzazione. Ci sono dei compromessi nell'usabilità; qualcun altro può commentare i trade-off della velocità. Allo stesso modo, è possibile imbattersi in problemi che spostano le implementazioni del bitfield su sistemi diversi se non si presta attenzione (in che modo il valore a 32 bit dovrebbe apparire su un sistema a 8 bit?). Sul rovescio della medaglia, in un piccolo sistema incorporato su cui ho lavorato una tonnellata di valori booleani di stato su una connessione seriale lenta, la codifica come bitfield era fondamentalmente una necessità.

    
risposta data 21.07.2016 - 17:28
fonte
3

What is the difference between a normal int and a 32-bit int?

Come sottolinea David Arno, non hai detto cosa intendi con un "normale" int.

So is what he saying is when you use bitwise operators in C++ it would only cost 1 bit of memory?

No, sta dicendo che se vuoi trattare gli interi come raccolte di bit, puoi farlo con operatori bit a bit.

when he talks about "memory" is this the RAM that the program takes up

Inizia non pensando più alla "memoria" e alla "RAM" come la stessa cosa. La memoria è la nozione astratta di archiviazione attiva; La RAM è solo una piccola parte di una strategia complessa per reificare quella nozione astratta. La memoria moderna è, per molti aspetti, meglio concepita come pagine di un file di scambio con RAM come cache.

Quindi, rendi la tua domanda più nitida. Con "la memoria che il programma occupa" intendi la memoria richiesta per caricare il programma stesso in memoria, o intendi la memoria dati consumata durante la sua esecuzione ? Se intendi il secondo, per "memoria" intendi memoria nel pool temporaneo o nel pool di archiviazione a lungo termine? Ognuno ha una diversa strategia di allocazione. Gestire correttamente la memoria è di vitale importanza in C ++. Se non si capisce la differenza tra l'archiviazione di breve durata e quella di lunga durata, si scriveranno programmi C ++ buggati. Assicurati di comprendere questa differenza molto chiaramente .

Am I looking at this in the wrong way?

Sembra probabile, sì.

    
risposta data 21.07.2016 - 17:39
fonte
2

Il titolo e il corpo della domanda fanno due domande diverse.

What is the difference between a normal int and a 32-bit int?

Non esiste un "normale" int . La dimensione di int in C ++ dipende dalla piattaforma e dal compilatore.

So is what he saying is when you use bitwise operators in C++ it would only cost 1 bit of memory?

La prima cosa da notare sulla tua citazione dal libro è l'affermazione "Sei sposato o non sei, sei maschio o femmina". Evidenzia un difetto nel pensare a entrambi i tratti che possono causare problemi nel codice. Entrambi gli esempi del mondo reale sono falsi. Nel Regno Unito, potresti essere single, convivente, in una società civile, sposato e convivente, sposato e separato, vedovo o divorziato. Non c'è "sposato / non sposato"; ci sono molti diversi stati di relazione, ciascuno con diverse ramificazioni legali. Allo stesso modo, uno non può essere né maschio né femmina. Oltre alle coppie di cromosomi XX e XY standard, alcune persone sono XXX, XXY, XXXX ecc. E alcune persone hanno 49 cromosomi e possono essere XXXY ecc. Questo porta a complicazioni nel determinare se qualcuno è eg femmina nello sport, con test per il cromosoma Y è stato abbandonato poiché alcuni che si identificano come femmine hanno un cromosoma Y. Ci sono molti stati di virilità e femminilità; non è una dicotomia.

Analogamente nella programmazione, se inizi a impacchettare i dati in bit, puoi imbatterti in situazioni in cui all'improvviso hai bisogno di una terza categoria (ad esempio quando qualcuno in una partnership civile lamenta che la tua app consente solo matrimonio / non sposato). A meno che non si stia lavorando su soluzioni specialistiche, la memoria è economica e funziona su tipi di dati più grandi di quelli che sono spesso più veloci.

Se stai lavorando su una soluzione in cui la memoria è stretta, e hai un sacco di stato che è veramente / o, allora le operazioni bit a bit possono essere utilizzate per impacchettare molti dati in un piccolo spazio. Ogni flag utilizza infatti solo un bit di memoria. Ricorda però che il compilatore in genere assegna 32/64 bit (a seconda dell'architettura) al valore contenente i dati bit a bit, quindi, a meno che non si disponga di un numero elevato di flag, non sarà necessario salvare la memoria.

I flag bitwise sono utili per le situazioni in cui hai un sacco di opzioni complementari, ma il loro vantaggio è nella facilità di testarli (usando bit per bit and e or ), non per risparmiare memoria.

    
risposta data 21.07.2016 - 17:28
fonte
1

In C ++, un int è almeno 16 bit. Un lungo (che ho visto indicato come int a 32 bit) ha almeno 32 bit.

Quando dichiari e inizializzi qualcosa, come long i = 0 , in realtà inizializzi almeno 32 bit di memoria. Se si utilizzano operazioni bit a bit, è possibile accedere a ciascun bit singolarmente.

Ad esempio, se hai 32 caratteri che hanno due opzioni (nel senso che possono essere codificati in un singolo bit), puoi usare un maschera di bit anziché avere 32 tratti separati. Ovviamente, questa è un'ottimizzazione per l'utilizzo della memoria piuttosto che per la leggibilità. Ci sono sempre dei compromessi quando fai qualcosa di simile.

    
risposta data 21.07.2016 - 17:13
fonte
-1

Quindi ogni volta che si inizializza una variabile con un determinato tipo di dati (int, float, long, double, ecc.) esso conserva un certo numero di bit per esso nella memoria. Una differenza fondamentale tra un numero floatpoint di 16 e 32 bit è l'intervallo di valori possibili, rispettivamente il numero di cifre.

Esempi: Nel caso di un numero a 16 bit è un intervallo da 3,1 · 10 ^ -5 a 6,6 · 10 ^ 4. Un numero a 32 bit servirebbe un intervallo da 1,5 · 10 ^ -45 a 1,5 · 10-45.

Per ulteriori informazioni su Datatypes, visita: Wikipedia: Tipo di dati

Spero che questo abbia aiutato un "bit"; -)

Mike

    
risposta data 21.07.2016 - 17:33
fonte

Leggi altre domande sui tag