Come vengono bit memorizzati nella memoria? (A pezzi? Ci può essere frammenti di diverse dimensioni memorizzati insieme?)

StackOverflow https://stackoverflow.com/questions/1546381

Domanda

Ho usato pensare che ogni posizione di memoria contiene 8, 16, 32 o 64 bit. Quindi 0101 saranno memorizzati in una macchina a 8 bit 00.000.101 (segno esteso se era negativo). Questo era tutto bene e dandy fino a quando ho scritto un programma in Java per la curiosità di scoprire alcune lavorazioni più interno di questo sistema.

Il metodo in questione si presenta così:

public void printBinaryRep(File f){
        try{
            FileInputStream inputStream = new FileInputStream(f);
            int next = 0;
            byte b = 0;
            while((next = inputStream.read()) != -1){
                b = (byte)next;
                System.out.println((char)next + " : "+Integer.toBinaryString(next));
            }
            inputStream.close();
        }
        catch(Exception e){System.out.println(e);}
 }

Ho avuto questa uscita da un file che dice Ciao Mondo

H : 1001000
e : 1100101
l : 1101100
l : 1101100
o : 1101111
  : 100000
W : 1010111
o : 1101111
r : 1110010
l : 1101100
d : 1100100

Tutto sembra bene, tranne per lo spazio. Ha 6 bit invece di 8. Ora sto chiedendo come tutte quelle informazioni sono memorizzate nella memoria. Se tutto questo è stato immagazzinato in 8 pezzi bit, come

Ciao: 10010001100101110110011011001101111

Poi si può semplicemente guardare ogni bit pezzo 8 e capire cosa il numero è che rappresenta (e quindi quale codice ASCII si riferisce a). Come funziona quando un carattere di dimensioni diverse (come lo spazio a 6 bit e 4 bit / n) viene memorizzato insieme a loro ?? Allora non sarebbe la memorizzazione di un numero ridotto in un grande spazio po 'sprecare un sacco di bit?

Credo di avere alcuni dei comprensione fondamentale sbagliato (o forse del programma sbagliato da qualche parte ...). Scusate se la domanda suona strano o troppo non-necessariamente approfondita. Voglio solo sapere. Ho fatto un po 'googling, ma non è venuto in mente nulla relevent. Se si riesce a farmi sapere dove ho sbagliato o indicarlo nella giusta direzione, sarei molto grato. Grazie!

È stato utile?

Soluzione

Si sarà meglio sperimentare in C e / o il montaggio, piuttosto che Java. Queste lingue sono di livello inferiore ed esporre direttamente lo spazio di indirizzo.

  

Ho usato per pensare che ogni memoria   posizione contiene 8, 16, 32 o 64   bit. Quindi 0101 saranno memorizzati in un 8   macchina po 'come 00000101 (segno esteso   se era negativo). Questo era tutto bene   e dandy fino a quando ho scritto un programma in   java per la curiosità di scoprire un po '   più funzionamento interno di questo sistema.

Tutte le posizioni di memoria in sistemi x86 contengono 8 bit (1 byte). Se un valore contiene più dati che può inserirsi in un singolo byte, viene memorizzato utilizzando più byte. Ad esempio, in C, tipo "flottante" è memorizzato usando 4 byte (32 bit).

  

Tutto si guarda bene tranne che per il   spazio. Ha 6 bit invece di 8. Sono   ora chiedo come tutto questo   le informazioni sono memorizzate nella memoria. Se   tutto questo è stato immagazzinato in 8 pezzi bit,   come

Lo spazio è anche memorizzato in un singolo byte. Il tuo codice di stampa sta dimenticando a pad fuori a 8 spazi. 100000 == 00100000 == 0x20.

Altri suggerimenti

Lo spazio ha 8 bit troppo. E 'solo che Integer.toBinaryString non stampa più importanti bit 0 il modo in cui è stato utilizzato.

Con tutti i bit iniziali 0, sembra in realtà come questo in memoria:

H : 01001000
e : 01100101
l : 01101100
l : 01101100
o : 01101111
  : 00100000
W : 01010111
o : 01101111
r : 01110010
l : 01101100
d : 01100100

La tua intuizione originale era (per lo più) corretto: tutte le posizioni di memoria sono costituite con lo stesso numero di bit. Su tutte le macchine moderne, ci sono otto bit di un "byte", dove un byte è il più piccolo pezzo di memoria che la macchina può accedere individualmente.

Guardate attentamente l'output. Lei ha sette cifre in tutti loro, ad eccezione dello spazio. Lo spazio sembra appena iniziare con due zeri nella sua rappresentazione binaria, mentre le altre lettere iniziano con uno.

In realtà il vostro approccio è sbagliato. La codifica è molto importante qui.

Se si utilizza ASCII allora si può facilmente dire che ogni carattere è memorizzato in un byte (otto bit), ma durante la codifica le modifiche non si può dire che.

Es: UTF-8 utilizza uno a tre byte (8 a 24 bit) per ciascun carattere in una stringa. È per questo che si vedrà un sovraccarico in cui è possibile specificare la codifica in oggetto InputStream.

La scelta di flusso di input sbagliato sarà assolutamente causare un'uscita stringa di sbagliato. Quindi è necessario conoscere la codifica del file per capire quali bit significa che cosa. In realtà FileInputStream fa per voi.

Se si memorizza una cifra come stringa ci vorrà una lunghezza char nel disco rigido. solo un altro personaggio.

Tuttavia, se si memorizzano 123456789 come stringa ASCII con codifica ci vorrà 9 * 8 bit = 72 bit.

Se si memorizzano questo come integer, (si noti la larghezza dati di interi differisce in ambienti diversi) ci vorranno solo 16 bit.

Inoltre, non si può essere sicuri che

H : 01001000
e : 01100101
l : 01101100
l : 01101100
o : 01101111
  : 00100000
W : 01010111
o : 01101111
r : 01110010
l : 01101100
d : 01100100
\n: 00001010

è memorizzato nel disco rigido come H: 01.001.000 e: 01100101 l: 01101100 l: 01101100 o: 01101111   : 00100000 W: 01010111 o: 01101111 R: 01110010 l: 01101100 d: 01100100 \ N: 00001010

Non si può essere sicuri di questo. File System non è così semplice. Forse Ciao è successivo, ma stringa Mondiale è alla fine del disco. Ecco perché v'è il comando defrag.

Ma se si parla di memoria principale (RAM) quando si definisce una stringa di bit mi aspetto di essere successiva. Almeno in C è. È possibile definire una stringa del genere.

char[100] value; // c is a char array. (there is no string type in c)

qui valore [0] è il primo carattere della nostra stringa. E il valore si rivolge solo alla posizione array char in memoria.

se il valore [0] 's indirizzo è 10 allora il valore [1]' s indirizzo è 10 + 8 = 18.

I numeri di computer negozio modo possono essere paragonati a un contachilometri in una macchina. Se il contachilometri ha 4 cifre, memorizza il numero 33 come "0033".

Se qualcuno chiede che cosa il chilometraggio è, non siete per dire "zero a zero mille centotrenta tre". Per impostazione predefinita, Java non lo fa neanche. (Anche se si può dire che a).

  
    

Quindi non sarebbe la memorizzazione di un numero ridotto in un grande spazio po 'sprecare un sacco di bit?

  

Beh, non proprio. Supponiamo che tu avessi 11.000.100 in memoria da qualche parte. Come si suppone che il computer per sapere se questo significa 11.000.100, o 11000 seguito da 100 o 1 seguito da 1000 seguito da 100, e così via?

Beh, in realtà il computer è solo seguendo il programma è dato (ricordiamo che un programma Java viene creata in parte da voi e in parte dalle persone che progettano Java). Se si riesce a creare un sistema praticabile per salvare i bit, è possibile rendere il computer farlo.

Tuttavia, tenere a mente che ci sia un compromesso in termini di utilizzo del processore e difficoltà di programmazione. Dal momento che un tipico computer può funzionare con i byte molto più velocemente di quanto si può con dire, i numeri a 7 bit o variabile bit, la memorizzazione di codici ASCII in byte è una scelta molto comune per la memorizzazione di testo.

Ma lasciatemi tornare alla tua domanda.

  
    

Quindi non sarebbe la memorizzazione di un numero ridotto in un grande spazio po 'sprecare un sacco di bit?

  

Matematicamente parlando, no. Un ramo della matematica chiamata Teoria ci dice che il numero di bit che sono assolutamente necessari dipende le possibilità che si desidera codificare e come probabilmente ognuno di essi è.

Supponiamo di avere solo quattro lettere dell'alfabeto (A, B, C, D), e utilizzare i numeri a due bit (00, 01, 10, 11 rispettivamente) per rappresentarla. Se ciascuna di queste lettere la stessa probabilità, allora il numero minimo di bit necessari per ogni lettera (in media) è 2. In altre parole, vi sono non bit sprecati, pur A è 00 e B è 01 .

D'altra parte, se si utilizza ASCII e codifica A, B, C, D come i numeri dopo 7-bit:

A: 1000001
B: 1000010
C: 1000011
D: 1000100

allora si sta "sprecando" 5 bit per lettera (anche se non si è "conservare piccoli numeri in un grande spazio bit").

Questi tipi di considerazioni sono importanti per la creazione algoritmi di compressione, e non così importante per everday applicazioni. E 'certamente importante capire bit e byte, se si vuole imparare il C.

Secondo la Java 4 API ,

  

Il valore intero senza segno è l'argomento più 232 se l'argomento è negativo; altrimenti   è uguale all'argomento. Questo valore viene convertito in una stringa di cifre ASCII in formato binario   (Base 2) senza 0s aggiuntivi leader.

In realtà, l'archiviazione dei dati è in realtà molto più complicato. Per efficienze in lavorazione, la maggior parte dei tipi di dati sono memorizzati in parola-confini, il che significa 4 byte su macchine a 32 bit o 8 byte su computer a 64 bit. Gli array possono essere imballati più da vicino, in modo che char [4] possono finire con la stessa quantità di "spazio reale", come char.

Java è una macchina virtuale, e io non sono certo ciò che l'architettura di memoria, se del caso, utilizza.

che cancella in su. Il mio problema principale era che stavo trascurando gli zeri all'inizio. Stavo sperimentando con questo come leggevo più su algoritmi di compressione (cioè, gzip) Stavo assumendo ASCII per tutto questo. Vedendo la rappresentazione non era l'obiettivo del programma, ma il diverso numero di bit per parola mi ha buttato fuori dalla meta originale di attuare una compressione di base, indice basato per un tipo di file su cui sto lavorando. Cercherò di riscriverlo in C una volta che ho un proof of concept in Java.

Grazie!

http: //docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#toBinaryString%28int%29
la specificazione di Integer.ToBinarys legge:

  

"Questo valore viene convertito in una stringa di cifre ASCII in binario (base 2)   senza 0 non significativi extra "

Che trascurato questo fatto è quello che ha portato alla confusione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top