2014-01-07 20:18:51 +0000 2014-01-07 20:18:51 +0000
369
369
Advertisement

Se le macchine a 32 bit possono gestire solo numeri fino a 2^32, perché posso scrivere 10000000000000000 (trilioni) senza che la mia macchina si blocchi?

Advertisement

I computer a 32 bit possono memorizzare solo numeri interi firmati fino a 231 - 1. Ecco perché abbiamo esaurito gli indirizzi IPv4 e siamo entrati nell'era dei 64 bit.

Tuttavia, il numero 231 - 1 (2.147.483.647) non è grande come il numero 1 trilione (1.000.000.000.000.000) che sembra che io sia in grado di visualizzare bene senza che la mia macchina si blocchi.

Qualcuno può spiegare perché questo è?

Advertisement

Risposte (18)

784
784
784
2014-01-07 20:31:38 +0000

Rispondo alla sua domanda chiedendole un'altra domanda:

Come si conta con le dita fino a 6?

Probabilmente si conta fino al numero più grande possibile con una mano e poi si passa alla seconda mano quando si esauriscono le dita. I computer fanno la stessa cosa, se devono rappresentare un valore più grande di quello che può contenere un singolo registro utilizzeranno più blocchi a 32 bit per lavorare con i dati.

395
395
395
2014-01-07 20:36:34 +0000

È corretto che un intero a 32 bit non può contenere un valore superiore a 2^32-1. Tuttavia, il valore di questo intero a 32 bit e il modo in cui appare sullo schermo sono due cose completamente diverse. La stringa stampata “10000000000000000” non è rappresentata da un intero a 32 bit in memoria.

Per visualizzare letteralmente il numero “100000000000000” sono necessari 13 byte di memoria. Ogni singolo byte può contenere un valore fino a 255. Nessuno di essi può contenere l'intero valore numerico, ma interpretato individualmente come caratteri ASCII (ad esempio, il carattere “0” è rappresentato dal valore decimale 48, il valore binario 00110000), possono essere uniti in un formato che ha senso per voi, un umano.


Un concetto correlato nella programmazione è typecasting, che è il modo in cui un computer interpreterà un particolare flusso di 0 e 1s. Come nell'esempio precedente, può essere interpretato come un valore numerico, un carattere o anche qualcosa di completamente diverso. Mentre un intero a 32 bit può non essere in grado di contenere un valore di 10000000000000000, un numero in virgola mobile a 32 bit sarà in grado di farlo, usando un'interpretazione completamente diversa.

Per quanto riguarda il modo in cui i computer possono lavorare con grandi numeri ed elaborarli internamente, esistono interi a 64 bit (che possono ospitare valori fino a 16 miliardi di miliardi di miliardi), valori in virgola mobile, così come librerie specializzate che possono lavorare con numeri arbitrariamente grandi.

190
Advertisement
190
190
2014-01-07 21:37:16 +0000

Innanzitutto, i computer a 32 bit possono memorizzare numeri fino a 2³²-1 ** in una singola parola macchina. Machine word è la quantità di dati che la CPU può elaborare in modo naturale (cioè le operazioni su dati di quelle dimensioni sono implementate in hardware e sono generalmente più veloci da eseguire). Le CPU a 32 bit utilizzano parole composte da 32 bit, quindi possono memorizzare numeri da 0 a 2³²-1 ** in una sola parola.

Secondo, 1 trilione e 100000000000000 sono due cose diverse.

  • 1 trilione è un concetto astratto di numero
  • 10000000000000000 è testo

Premendo 1 una volta e poi 0 12 volte si digita testo. 1 ingressi 1, 0 ingressi 0. Vedi? Stai digitando dei caratteri. I caratteri non sono numeri. Le macchine da scrivere non hanno CPU o memoria e gestiscono piuttosto bene questi “numeri”, perché è solo testo.

Prova che 10000000000000000 non è un numero, ma testo: può significare 1 trilione (in decimale), 4096 (in binario) o 2814749797676710656 (in esadecimale). Ha ancora più significati in sistemi diversi. Il significato di 10000000000000000 è un numero e memorizzarlo è una storia diversa (ci torneremo tra un attimo).

Per memorizzare il testo (in programmazione si chiama stringa) 100000000000000 sono necessari 14 byte (uno per ogni carattere più un byte di terminazione NULL che in pratica significa “la stringa finisce qui”). Sono 4 parole macchina. 3 e mezzo sarebbero sufficienti, ma come ho detto, le operazioni sulle parole macchina sono più veloci. Supponiamo che ASCII sia usato per la memorizzazione del testo, quindi in memoria sarà così: (convertendo i codici ASCII corrispondenti a 0 e 1 in binari, ogni parola in una riga separata)

00110001 00110000 00110000 00110000
00110000 00110000 00110000 00110000
00110000 00110000 00110000 00110000
00110000 00000000 00000000 00000000
``` ```
0 0
0 0

Quattro caratteri si inseriscono in una parola, il resto viene spostato a quella successiva. Il resto viene spostato alla parola successiva fino a quando tutto (compreso il primo byte NULL) si adatta.

Ora, torniamo alla memorizzazione dei numeri. Funziona proprio come con il testo straripante, ma si adattano da destra a sinistra. Può sembrare complicato, quindi ecco un esempio. Per semplicità supponiamo che:

  • il nostro computer immaginario usa decimali invece di binari
  • un byte può contenere numeri 0..9
  • una parola è composta da due byte

Ecco una memoria vuota di 2 parole:

0 4
0 0
``` ```
1 3
0 0

Memorizziamo il numero 4:

9 9
0 0
``` ```
0 0
0 0

Ora aggiungiamo 9:

0 0
9 9
``` ```
0 1
0 0

Si noti che entrambi gli operandi starebbero in un byte, ma non il risultato. Ma ne abbiamo un altro pronto all'uso. Ora memorizziamo 99:

0099 | +1
0100
``` ```
00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111 | +1
00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000000

Ancora una volta, abbiamo usato il secondo byte per memorizzare il numero. Aggiungiamo 1:

&001 &001

Ops… Questo si chiama integer overflow ed è causa di molti problemi seri, a volte molto costosi .

Ma se ci aspettiamo che si verifichi uno straripamento, possiamo farlo:

&001 &001

E ora aggiungiamo 1:

&001 &001

Diventa più chiaro se si rimuovono gli spazi di separazione dei byte e le nuove linee:

&001 &001

Abbiamo previsto che potrebbe verificarsi uno straripamento e potremmo aver bisogno di memoria aggiuntiva. La gestione dei numeri in questo modo non è così veloce come con i numeri che si adattano a singole parole e deve essere implementata nel software. L'aggiunta del supporto per i numeri di parole a due-32 bit a una CPU a 32 bit la rende effettivamente una CPU a 64 bit (ora può operare su numeri a 64 bit in modo nativo, giusto?).

Tutto ciò che ho descritto sopra si applica alla memoria binaria con byte a 8 bit e parole a 4 byte, funziona più o meno allo stesso modo:

&001 &001

La conversione di tali numeri in sistema decimale è comunque complicata. (ma funziona abbastanza bene con l'esadecimale ](https://math.stackexchange.com/q/597019))

40
40
40
2014-01-07 23:06:37 +0000

Siete anche in grado di scrivere “QUESTA DICHIARAZIONE È FALSA” senza che il vostro computer si blocchi :) La risposta di @Scott è azzeccata per certi quadri di calcolo, ma la vostra domanda di “scrivere” un numero elevato implica che si tratta solo di testo semplice, almeno fino a quando non viene interpretato.

Modifica: ora con senza sarcasmo informazioni più utili su diversi modi in cui un numero può essere memorizzato. Li descriverò con a più alta astrazione, cioè in termini che un moderno programmatore può scrivere codice prima che venga tradotto in codice macchina per l'esecuzione.

I dati su un computer devono essere limitati ad un certo tipo, e una definizione computerizzata di questo tipo descrive quali operazioni possono essere eseguite su questi dati e come (cioè confrontare numeri, testo concatenato o XOR un booleano). Non si può semplicemente aggiungere del testo ad un numero, così come non si può moltiplicare un numero per il testo, così alcuni di questi valori possono essere convertiti tra i tipi.

Iniziamo con unsigned integers. In questi tipi di valore, tutti i bit sono usati per memorizzare informazioni sulle cifre; il vostro è un esempio di 32-bit integer senza segno, dove qualsiasi valore da 0 a 2^32-1 può essere memorizzato. E sì, a seconda del linguaggio o dell'architettura della piattaforma utilizzata si possono avere interi a 16 bit o interi a 256 bit.

E se si vuole ottenere un valore negativo? Intuitivamente, neri interi firmati è il nome del gioco. La convenzione è di assegnare tutti i valori da -2^(n-1) a 2^(n-1)-1 - in questo modo si evita la confusione di dover affrontare due modi di scrivere +0 e -0. Quindi un intero firmato a 32 bit terrebbe un valore da -2147483648 a 2147483647. Bello, vero?

Ok, abbiamo trattato gli interi che sono numeri senza componente decimale. Esprimere questi è più complicato: la parte non intera può ragionevolmente essere solo da qualche parte tra 0 e 1, quindi ogni bit in più usato per descriverla aumenterebbe la sua precisione: ½, ¼, 1/8… Il problema è che non si può esprimere con precisione un semplice decimale 0.1 come somma di frazioni che possono avere solo una potenza di due nel loro denominatore! Non sarebbe molto più semplice memorizzare il numero come intero, ma acconsentire a mettere invece il punto radix (decimale)? Questo si chiama numeri a punto fisso, dove memorizziamo 1234100 ma concordiamo una convenzione per leggerlo invece come 1234.100.

Un tipo relativamente più comune usato per i calcoli è floating point. Il modo in cui funziona è davvero pulito, usa un bit per memorizzare il valore del segno, poi alcuni per memorizzare l'esponente e il significato. Ci sono standard che definiscono tali allocazioni, ma per un 32-bit float il numero massimo che si sarebbe in grado di memorizzare è un

(2 - 2^-23) * 2^(2^7 - 1) ≈ 3.4 * 10^38

. Il JavaScript disponibile nei browser utilizza i galleggianti a 64 bit, e non riesce ancora a fare le cose per bene. Basta copiarlo nella barra degli indirizzi e premere invio. Spoiler alert: il risultato è non sarà 0.3.

javascript:alert(0.1+0.2);
``` &001 


Ci sono altri tipi alternativi come [ `BigInteger` ](http://msdn.microsoft.com/en-us/library/system.numerics.biginteger.aspx) di Microsoft .NET 4.5, che teoricamente non ha limiti superiori o inferiori e deve essere calcolato in "lotti"; ma forse le tecnologie più affascinanti sono quelle che _comprendono_ la matematica, come il motore Wolfram Mathematica, che può funzionare con precisione con valori astratti come [ infinity ](http://www.wolframalpha.com/input/?i=infinity%20/%202).
31
Advertisement
31
31
2014-01-07 21:58:50 +0000

La chiave è capire come i computer encode numeri.

Vero, se un computer insiste nel voler memorizzare i numeri usando una semplice rappresentazione binaria del numero con una sola parola (4 byte su un sistema a 32 bit), allora un computer a 32 bit può memorizzare solo numeri fino a 2^32. Ma ci sono molti altri modi per codificare i numeri a seconda di ciò che si vuole ottenere con essi.

Un esempio è come i computer memorizzano i numeri a virgola mobile. I computer possono usare un sacco di modi diversi per codificarli. Lo standard IEEE 754 definisce le regole per la codifica di numeri più grandi di 2^32. Crudelmente, i computer possono implementare questa regola dividendo i 32 bit in parti diverse che rappresentano alcune cifre del numero e altri bit che rappresentano la dimensione del numero (cioè l'esponente, 10^x). Questo permette un range di numeri molto più ampio in termini di dimensioni, ma ne compromette la precisione (che va bene per molti scopi). Naturalmente il computer può anche usare più di una parola per questa codifica, aumentando la precisione della grandezza dei numeri codificati disponibili. La semplice versione decimale 32 dello standard IEEE permette numeri con circa 7 cifre decimali di precisione e numeri fino a circa 10^96 di grandezza.

Ma ci sono molte altre opzioni se si ha bisogno di una maggiore precisione. Ovviamente è possibile utilizzare più parole nella codifica senza limiti (anche se con una penalità di prestazione per la conversione da e verso il formato codificato). Se volete esplorare un modo in cui questo può essere fatto c'è un grande add-in open-source per Excel che utilizza uno schema di codifica che permette centinaia di cifre di precisione nel calcolo. L'add-in si chiama Xnumbers ed è disponibile qui . Il codice è in Visual Basic che non è il più veloce possibile ma ha il vantaggio che è facile da capire e modificare. È un ottimo modo per imparare come i computer ottengono la codifica di numeri più lunghi. E si può giocare con i risultati all'interno di Excel senza dover installare alcuno strumento di programmazione.

24
24
24
2014-01-07 23:47:36 +0000

È tutto nella tua domanda.

Puoi scrivere qualsiasi numero tu voglia sulla carta. Prova a scrivere un trilione di punti su un foglio di carta bianca. È lento e inefficace. Ecco perché abbiamo un sistema a 10 cifre per rappresentare quei grandi numeri. Abbiamo anche nomi per i grandi numeri come “milioni”, “trilioni” e altri ancora, così non si dice one one one one one one one one one one one... ad alta voce.

I processori a 32 bit sono progettati per lavorare nel modo più veloce ed efficiente con blocchi di memoria lunghi esattamente 32 cifre binarie. Ma noi, gente, comunemente usiamo sistemi numerici a 10 cifre, e i computer, essendo elettronici, usano sistemi a 2 cifre binari ). I numeri 32 e 64 sono solo poteri di 2. Così sono un milione e un trilione sono poteri di 10. È più facile per noi operare con questi numeri che con moltitudini di 65536, per esempio.

Rompiamo i grandi numeri in cifre quando li scriviamo su carta. I computer scompongono i numeri in un numero maggiore di cifre. Possiamo scrivere qualsiasi numero a nostro piacimento, e lo stesso vale per i computer se li progettiamo.

15
Advertisement
15
15
2014-01-08 00:42:45 +0000

32bit e 64bit si riferiscono agli indirizzi di memoria. La memoria del vostro computer è come le caselle postali, ognuna ha un indirizzo diverso. La CPU (Central Processing Unit) utilizza questi indirizzi per indirizzare le posizioni di memoria sulla vostra RAM (Random Access Memory). Quando la CPU poteva gestire solo indirizzi a 16bit, si potevano utilizzare solo 32mb di RAM (che all'epoca sembrava enorme). Con 32bit si è passati a 4+gb (che all'epoca sembrava enorme). Ora che abbiamo indirizzi a 64bit la RAM va in terabyte (che sembra enorme). Tuttavia il programma è in grado di allocare più blocchi di memoria per cose come la memorizzazione di numeri e testo, che è a discrezione del programma e non in relazione alla dimensione di ogni indirizzo. Così un programma può dire alla CPU, userò 10 blocchi di indirizzi di memoria e poi memorizzerò un numero molto grande, o una stringa di 10 lettere o qualsiasi altra cosa. Nota a margine: Gli indirizzi di memoria sono puntati da “puntatori”, quindi il valore a 32 e 64 bit indica la dimensione del puntatore usato per accedere alla memoria.

13
13
13
2014-01-08 06:44:38 +0000

Perché la visualizzazione del numero è fatta usando caratteri singoli, non interi. Ogni cifra del numero è rappresentata con un carattere letterale separato, il cui valore intero è definito dalla codifica utilizzata, ad esempio 'a' è rappresentato con il valore ascii 97, mentre '1' è rappresentato con 49. Controllare la tabella ascii qui . Per visualizzare sia ‘a’ che ‘1’ è uguale. Sono caratteri letterali, non interi. Ogni carattere letterale può avere un valore massimo di 255 in una piattaforma a 32 bit che memorizza il valore in 8 bit o 1 byte (che dipende dalla piattaforma, tuttavia 8 bit è la dimensione del carattere più comune), quindi possono essere raggruppati insieme e possono essere visualizzati. La quantità di caratteri separati che possono essere visualizzati dipende dalla RAM che si ha a disposizione. Se si dispone di 1 solo byte di RAM allora si può visualizzare un solo carattere, se si dispone di 1GB di RAM, si possono visualizzare bene 1024*1024*1024 caratteri(Troppo pigri per fare i conti).

Questa limitazione si applica comunque ai calcoli, tuttavia credo che siate interessati allo standard IPV4. Anche se non è interamente correlato al bit-size dei computer, in qualche modo ha influito sugli standard. Quando lo standard IPV4 è stato creato, i valori ip sono stati memorizzati in numeri interi a 32 bit. Ora, una volta data la dimensione, è diventato standard. Tutto ciò che sappiamo di internet dipendeva da questo, e poi abbiamo finito gli indirizzi IP da assegnare. Quindi, se lo standard IP è stato rivisto per avere 64 bit, tutto ha smesso di funzionare, compreso il router (presumo che questo sia corretto) e gli altri dispositivi di rete. Quindi è necessario creare un nuovo standard, che ha appena sostituito il 32 bit intero con uno a 128 bit. E regolato il resto dello standard. Il produttore di hardware deve solo dichiarare che supporta questo nuovo standard e diventerà virale. Anche se non è così semplice, ma credo che il punto sia chiaro.

Disclaimer: La maggior parte dei punti menzionati qui sono fedeli alla mia supposizione. Potrei aver tralasciato dei punti importanti per semplificare le cose. Non sono bravo con i numeri, così deve aver perso alcune cifre, ma il mio punto qui è quello di rispondere alla risposta dell'OP sul perché non si bloccherà il PC.

13
Advertisement
13
13
2014-01-08 11:27:08 +0000

Nei processori, ci sono “parole”. Ci sono parole diverse. Quando si dice “processore a 32 bit”, si intende per lo più “larghezza del bus di memoria”. Questa parola consiste di diversi “campi”, che si riferiscono a sottosistemi di computer corrispondenti alla trasmissione (24 bit) e al controllo (altri bit). Posso sbagliarmi sui numeri esatti, accertatene con i manuali.

L'aspetto completamente diverso è il calcolo. I set di istruzioni SSE e MMX possono memorizzare lunghi numeri interi. La lunghezza massima senza perdita di produttività dipende dalla versione SSE corrente, ma si tratta sempre di un multiplo di 64 bit.

Gli attuali processori Opteron possono gestire numeri larghi 256 bit (non sono sicuro dell'intero, ma il float è sicuro).

Riepilogo : (1) la larghezza del bus non è collegata direttamente alla larghezza di calcolo, (2) anche parole diverse (parola di memoria, parola di registro, parola del bus ecc.) non sono collegate tra loro, altre hanno divisori comuni circa 8 o 16 o 24. Molti processori hanno usato anche la parola a 6 bit (ma la sua storia).

10
10
10
2014-01-08 20:39:13 +0000

Lo scopo di un dispositivo di calcolo, in generale, è quello di accettare, elaborare, memorizzare ed emettere dati. L'hardware sottostante è semplicemente una macchina che aiuta a svolgere queste quattro funzioni. Il software è il codice che dice alla macchina come accettare i dati, come elaborarli, come immagazzinarli e come fornirli agli altri.

L'hardware sottostante avrà sempre delle limitazioni. Nel caso di una macchina a 32 bit, la maggior parte dei registri che elaborano i dati sono larghi solo 32 bit. Questo non significa, però, che la macchina non possa gestire numeri superiori a 2^32, significa che se si vuole trattare di numeri più grandi, la macchina può impiegare più di un ciclo per accettarli, elaborarli, memorizzarli o emetterli.

Il software dice alla macchina come gestire i numeri. Se il software è progettato per gestire numeri grandi, invia una serie di istruzioni alla CPU che le dicono come gestire i numeri più grandi. Ad esempio, il numero può essere rappresentato da due registri a 32 bit. Se si volesse aggiungere 1.234 al proprio numero, il software direbbe alla CPU di aggiungere prima 1.234 al registro inferiore, poi controllerebbe il bit di overflow per vedere se quell'aggiunta ha portato ad un numero troppo grande per il registro inferiore. Se è così, allora aggiunge 1 al registro superiore.

Nello stesso modo in cui ai bambini delle scuole elementari viene insegnato ad aggiungere con il carry, alla CPU può essere detto di gestire numeri più grandi di quelli che può contenere in un singolo registro. Questo vale per la maggior parte delle operazioni matematiche generiche, per numeri di qualsiasi dimensione pratica.

8
Advertisement
8
8
2014-01-09 15:18:54 +0000

I computer a 32 bit possono memorizzare solo numeri fino a 2^32 in una singola parola macchina, ma ciò non significa che non possano gestire entità di dati più grandi.

Il significato di un computer a 32 bit è generalmente che il bus dati e il bus indirizzi è largo 32 bit, il che significa che il computer può gestire 4 GB di spazio di indirizzo di memoria in una sola volta, e inviare quattro byte di dati alla volta attraverso il bus dati.

Questo tuttavia non limita il computer dal gestire più dati, deve solo dividere i dati in blocchi di quattro byte quando viene inviato sul bus dati.

Il normale processore Intel a 32 bit può gestire internamente numeri a 128 bit, il che permette di gestire numeri come 10000000000000000000000000000000000000000000000000000000000000000 senza alcun problema.

Si possono gestire numeri molto più grandi di quelli di un computer, ma poi i calcoli devono essere fatti da software, la CPU non ha istruzioni per gestire numeri più grandi di 128 bit. (Può gestire numeri molto più grandi sotto forma di numeri a virgola mobile, ma allora si hanno solo 15 cifre di precisione).

6
6
6
2014-01-10 19:11:43 +0000

Aggiungo solo una nota alle tante altre risposte, perché questo è un fatto piuttosto importante in questa domanda che è stato tralasciato.

“32 bit” si riferisce alla larghezza dell'indirizzo di memoria. Non ha nulla a che vedere con la dimensione del registro. Molte CPU a 32 bit hanno probabilmente registri a 64 o anche 128 bit. In particolare riferendosi alla linea di prodotti x86, le recenti CPU di consumo, che sono tutte a 64 bit, possiedono fino a 256 bit di registri per scopi speciali.

Questa differenza tra la larghezza del registro e la larghezza dell'indirizzo esiste fin dai tempi antichi, quando avevamo registri a 4 bit e indirizzi a 8 bit, o viceversa.

È semplice vedere che la memorizzazione di un numero elevato non è un problema indipendentemente dalla dimensione del registro, come spiegato in altre risposte.

Il motivo per cui i registri, di qualsiasi dimensione essi siano, possono anche calcolare con numeri più grandi, è che calcoli troppo grandi possono essere scomposti in diversi più piccoli che si inseriscono nei registri (in realtà è solo un po’ più complicato).

6
Advertisement
6
6
2014-01-10 21:36:01 +0000

Le risposte già date sono in realtà piuttosto buone, ma tendono ad affrontare la questione da diversi punti di vista e quindi presentano un quadro incompleto. Sono anche un po’ eccessivamente tecniche, a mio parere.

Quindi, tanto per chiarire qualcosa che è accennato ma non esplicitamente espresso in nessuna delle altre risposte, e che penso sia il nocciolo della questione:

Stai confondendo diversi concetti nella tua domanda , e uno di essi (“32 bit”) può in realtà riferirsi a una varietà di cose diverse (e le diverse risposte hanno assunto interpretazioni diverse). Questi concetti hanno tutti qualcosa a che fare con il numero di bit (1 e 0) utilizzati (o disponibili) in vari contesti informatici (ciò che intendo con questo sarà, si spera, chiarito dagli esempi che seguono), ma i concetti sono altrimenti non correlati.

Esplicitamente:

  • “IPv4/6” si riferisce a protocollo internet , un insieme di regole che definiscono come le informazioni devono essere confezionate e interpretate su internet. La principale (o almeno la più nota) distinzione tra IPv4 e IPv6 è che il spazio dell'indirizzo (cioè l'insieme di indirizzi che possono essere usati per distinguere tra diverse località della rete) è più grande in IPv6. Ciò ha a che fare con quanti bit in ogni pacchetto di dati inviati attraverso la rete sono allocati per (cioè messi da parte allo scopo di) identificare il mittente e il destinatario del pacchetto.
  • Analogia non informatica: Ogni pacchetto è come una lettera inviata per posta elettronica, e lo spazio dell'indirizzo è come la quantità di caratteri che è “permesso” utilizzare quando si scrive l'indirizzo e l'indirizzo di ritorno sulla busta.
  • Non vedo questo aspetto menzionato in nessuna delle altre risposte finora.
  • Le “parole” della memoria del computer (32-bit e 64-bit) possono essere generalmente pensate come il più piccolo pezzo di dati che un computer usa, o “pensa” in. Questi bit di dati si uniscono per formare altri bit di dati, come pezzi di testo o interi più grandi.
  • Analogia non informatica: le parole possono essere pensate un po’ come lettere che compongono le parole su carta, o anche come parole individuali in un treno di pensieri.
  • Si veda risposta di Guffa , risposta di sanaris , e il primo paragrafo della risposta di gronostaj .
  • Gli puntatori a 32 bit possono essere o meno parole, ma sono comunque trattati atomicamente (cioè come unità individuali che non possono essere scomposte in componenti più piccole). I puntatori sono il modo più basso in cui un computer può registrare la posizione in memoria di alcuni pezzi di dati arbitrari. Si noti che la dimensione del puntatore usato dal computer (o, in realtà, dal sistema operativo) limita la gamma di memoria a cui può accedere un singolo puntatore, poiché ci sono solo quante più posizioni di memoria possibili a cui un puntatore può “puntare” come ci sono possibili valori per il puntatore stesso. Ciò è analogo al modo in cui l'IPv4 limita la gamma di indirizzi internet possibili, ma non limita la quantità di dati che possono essere presenti, ad esempio, in una particolare pagina web. Tuttavia, la dimensione del puntatore non limita la dimensione dei dati stessi a cui il puntatore può puntare. (Per un esempio di uno schema per permettere che la dimensione dei dati superi l'intervallo del puntatore, controllare la inode pointer structure di Linux. Si noti che questo è un uso leggermente diverso della parola “puntatore” rispetto a quello tipico, poiché il puntatore di solito si riferisce ad un puntatore nella memoria ad accesso casuale, non nello spazio del disco rigido)
  • Analogia non informatica: hmmmmmm….questo è un po’ complicato. Forse il sistema decimale Dewey per l'indicizzazione dei materiali della libreria è un po’ simile? O qualsiasi sistema di indicizzazione, in realtà.
  • Vedi Risposta di SiteNook .
  • Si prega di notare che la mia spiegazione dei puntatori sopra elide alcuni dettagli sottili e probabilmente non è del tutto corretta. Tuttavia, nei linguaggi di programmazione in cui i programmatori lavorano direttamente con i puntatori, la modalità mentale che ho disegnato è di solito sufficiente per scopi pratici.
  • I numeri che un computer è “in grado di visualizzare ” non sono (per scopi pratici) limitati dall'hardware o dal sistema operativo del computer; essi sono trattati come qualsiasi altro testo.
  • Analogia non informatica: scrivere su un pezzo di carta
  • Si veda risposta dell'utente1306322 e risposta di Bigbio2002 (http://en.wikipedia.org/wiki/Turing_machine)

Si noti che questo non è inteso come un elenco completo di interpretazioni per la frase “32 bit”.

Credito extra: per vedere veramente la distinzione filosofica a nudo tra numeri e pezzi primitivi di memoria del computer, leggere un po’ [ Turing machines ]&003.

5
5
5
2014-01-11 23:24:10 +0000

Nella vostra mente conoscete solo 10 cifre diverse. Da 0 a 9. All'interno del vostro cervello, questo è certamente codificato in modo diverso rispetto a quello di un computer.

Un computer usa i bit per codificare i numeri, ma questo non è importante. Questo è solo il modo in cui gli ingegneri hanno scelto di codificare le cose, ma dovreste ignorarlo. Si può pensare che un computer a 32 bit abbia una rappresentazione unica di oltre 4 miliardi di valori diversi, mentre noi esseri umani abbiamo una rappresentazione unica per 10 valori diversi.

Ogni volta che dobbiamo comprendere un numero più grande, usiamo un sistema. Il numero più a sinistra è il più importante. È 10 volte più importante del prossimo.

Un computer in grado di differenziare quattro miliardi di valori diversi, dovrà analogamente rendere il valore più a sinistra, in un insieme di valori, quattro miliardi di volte più importante del valore successivo in quell'insieme. In realtà un computer non si preoccupa affatto. Non assegna “importanza” ai numeri. I programmatori devono fare un codice speciale per occuparsene.

Ogni volta che un valore diventa maggiore del numero di simboli unici, 9 in una mente umana, se ne aggiunge uno al numero a sinistra.

3+3=6
``` ```
5+5=10. This situation is called an overflow.

In questo caso, il numero si inserisce ancora all'interno di un singolo “slot”

987+321 is more difficult.
``` ```
7+1=8, we now have ...8 as the result so far

Quindi gli esseri umani affrontano sempre il problema di non avere abbastanza simboli unici. A meno che il computer non abbia un sistema per affrontare questo problema, si limiterebbe a scrivere 0, dimenticando che c'era un numero in più. Per fortuna i computer hanno una “bandiera di trabocco” che in questo caso si alza.

8+2=10, the overflow flag is raised. We now have ...08, plus overflow.
``` ```
9+3=12, and then we add one due to overflow. ...308, and we had another overflow.

Forse avete imparato un metodo a scuola. Un algoritmo. L'algoritmo è abbastanza semplice. Iniziate aggiungendo i due simboli più a sinistra.

1308
``` &001 


Poi passate alla slot successiva ed eseguite la stessa aggiunta. 



&001 &001 


Poiché abbiamo avuto un overflow, significa che dobbiamo aggiungere 1 al numero successivo. 


&001 &001 

Non ci sono più numeri da aggiungere, quindi creiamo semplicemente uno slot ed inseriamo 1 perché il flag di overflow è stato alzato. 


&001 &001 


Un computer lo fa esattamente allo stesso modo, tranne che ha 2^32 o meglio ancora 2^64 simboli diversi, invece che solo 10 come gli esseri umani. 


A livello hardware, il computer lavora su singoli bit usando esattamente lo stesso metodo. Per fortuna, questo è astratto per i programmatori. I bit sono solo due cifre, perché è facile da rappresentare in una linea elettrica. O la luce è accesa, o è spenta. 

Infine, un computer può visualizzare qualsiasi numero come una semplice sequenza di caratteri. Questo è ciò in cui i computer sono più bravi. L'algoritmo di conversione tra una sequenza di caratteri e una rappresentazione interna è piuttosto complesso.
5
Advertisement
5
5
2014-01-11 17:59:58 +0000

Nel caso si desideri un esempio pratico di quanti programmi su un tipico sistema Linux gestiscono l'elaborazione e l'output di grandi numeri:

libgmp - La libreria GNU Multiple Precision Arithmetic Library è la libreria più usata per questo scopo sui sistemi Linux. Un semplice esempio di moltiplicazione 2^80 per 1000:

#include <gmp.h>

// Each large integer uses the mpz_t type provided by libgmp
mpz_t a_large_number;
mpz_t base;
mpz_t result;

// Initalize each variable
mpz_init(a_large_number);
mpz_init(base);
mpz_init(result);

// Assign the number 2 to the variable |base|
mpz_set_ui(base, 2);

// Raise base^80 (2^80), store the result in |a_large_number|
mpz_pow_ui(a_large_number, base, 80);

// Multiply |a_large_number| by 1000, store the result in |result|
mpz_mul_ui(result, a_large_number, 1000);

// Finally, output the result in decimal and hex notation
gmp_printf("decimal: %Zd, hex: %ZX\n", result, result);
``` &001 


Quindi fondamentalmente è la stessa cosa che usare i normali + - \* / operatori, solo con una libreria per scomporre i numeri e memorizzarli internamente come numeri di parole macchina multipli di dimensioni (cioè a 32 bit). Ci sono anche funzioni di tipo scanf() per gestire la conversione dell'input di testo in tipi interi. 


La struttura di `mpz_t` è esattamente come l'esempio di Scott Chamberlain di contare fino a 6 usando due mani. Si tratta fondamentalmente di un array di tipi `mp_limb_t` delle dimensioni di una parola macchina, e quando un numero è troppo grande per entrare in una parola macchina, GMP usa più `mp_limb_t` per memorizzare le parti alte/basse del numero.
5
5
5
2014-01-09 16:36:20 +0000

Se si scrive 1000000000000000000 ad esempio in calcolatrice, il computer lo calcolerà come un numero di tipo reale** con punto decimale. Il limite per 32 bit che hai citato tocca più tutti i numeri Di tipo senza punto decimale**. Diversi tipi di dati usano metodi diversi per entrare in bit/byte.

Numeri di tipo di numero: Questa tabella potrebbe aiutarla a cogliere il punto http://msdn.microsoft.com/en-us/library/296az74e.aspx ). Questo tocca i limiti per C++. Per esempio Il numero di tipoInt64 ha limiti da -922337203685854775808 a 9223372036854775807.

Numeri di tipo reale : I numeri di tipo reali contengono un valore con punto fluttuante e esponente e si possono inserire numeri molto più grandi, ma con una precisione/precisione limitata. http://msdn.microsoft.com/en-us/library/6bs3y5ya.aspx ) Per esempio LDBL (doppio grande) in C++ ha il massimo esponente 308, quindi possibilmente si può inserire o avere come risultato il numero 9.999 x 10^308, significa che si avranno teoricamente 308(+1) cifre di 9 ma solo 15 cifre più importanti saranno usate per rappresentarlo, il resto andrà perso, causa della limitata precisione.

Inoltre, ci sono diversi linguaggi di programmazione e potrebbero avere diverse implementazioni dei limiti numerici. Quindi si può immaginare che le applicazioni specializzate possano gestire numeri molto più grandi (e/o più esatti/precisi) rispetto al C++.

3
Advertisement
3
3
2014-01-12 00:41:20 +0000

Perché non si sta visualizzando un numero (per quanto riguarda il computer), ma una stringa , o una sequenza di cifre. Certo, alcune applicazioni (come la calcolatrice, credo), che si occupano di numeri, possono gestire un tale numero, credo. Non so quali trucchi usano… Sono sicuro che alcune delle altre risposte più elaborate coprono questo aspetto.

0
0
0
2016-12-30 11:54:31 +0000

La maggior parte del contenuto di questa risposta proveniva originariamente da questa risposta (scritta prima che l'altra domanda fosse segnata come un duplicato). Quindi discuto l'uso di valori a 8 bit (anche se questa domanda riguardava valori a 32 bit), ma va bene perché i valori a 8 bit sono più semplici da capire concettualmente, e gli stessi concetti si applicano a valori più grandi come l'aritmetica a 32 bit.

Quando si aggiungono due numeri che sono a 8 bit, il numero più grande che si può ottenere (0xFF + 0xFF = 1FE). Infatti, se si moltiplicano due numeri che sono a 8 bit, il numero più grande che si può ottenere (0xFF * 0xFF = 0xFE01) è ancora 16 bit, due volte di 8 bit.

Ora, si può supporre che un processore x-bit possa tenere traccia solo degli x-bit. (Per esempio, un processore a 8 bit può tenere traccia solo di 8 bit). Il processore a 8 bit riceve i dati in blocchi di 8 bit (questi “blocchi” hanno tipicamente un termine formale: “parola”. Su un processore a 8 bit si usano parole a 8 bit. Su un processore a 64 bit, si possono usare parole a 64 bit.)

Quindi, quando si danno al computer 3 byte: Byte #1: l'istruzione MUL Byte #2: i byte di ordine elevato (ad esempio, 0xA5) Byte #3: i byte di ordine inferiore (ad esempio, 0xCB) Il computer può generare un risultato che è superiore a 8 bit. La CPU può generare risultati come questo: 0100 0000 0100 0010 xxxx xxxx xxxx xxxx xxxx xxxx 1101 0111 a.k.a.: 0x4082xxxxxxD7 Ora, lasciatemi interpretare questo per voi: 0x significa solo che le seguenti cifre sono esadecimali.
Parlerò brevemente del “40” in dettaglio. 82 fa parte del registro “A”, che è una serie di 8 bit. xx e xx fanno parte di altri due registri, denominati registro “B” e registro “C”. Il motivo per cui non ho riempito quei bit con zeri o uno è che un'istruzione “ADD” (inviata alla CPU) può far sì che quei bit rimangano invariati dall'istruzione (mentre la maggior parte degli altri bit che uso in questo esempio possono essere alterati, ad eccezione di alcuni dei flag bit). D7 entrerebbe in più bit, chiamato registro “D”. Un registro è solo un pezzo di memoria. I registri sono integrati nelle CPU, quindi la CPU può accedere ai registri senza dover interagire con la memoria su una chiavetta RAM.

Quindi il risultato matematico di 0xA5 volte 0xCB è 0x82D7.

Ora, perché i bit sono stati divisi nei registri A e D invece che nei registri A e B, o nei registri C e D? Bene, ancora una volta, questo è uno scenario di esempio che sto usando, pensato per essere piuttosto simile in concetto ad un vero e proprio linguaggio Assembly (Intel x86 16-bit, come usato dagli Intel 8080 e 8088 e molte CPU più recenti). Ci potrebbero essere alcune regole comuni, come il registro “C” usato tipicamente come indice per le operazioni di conteggio (tipico per i loop), e il registro “B” usato per tenere traccia degli offset che aiutano a specificare le posizioni di memoria. Quindi, “A” e “D” possono essere più comuni per alcune delle funzioni aritmetiche comuni.

Ogni istruzione della CPU dovrebbe avere una certa documentazione, usata da chi programma in Assembly. Tale documentazione dovrebbe specificare quali registri vengono utilizzati da ciascuna istruzione. (Quindi la scelta di quali registri utilizzare è spesso specificata dai progettisti della CPU, non dai programmatori del linguaggio Assembly. Anche se ci può essere una certa flessibilità).)

Ora, tornando al “40” nell'esempio precedente: si tratta di una serie di bit, spesso chiamati “flag register”. Ogni bit del registro delle bandiere ha un nome. Per esempio, c'è un bit “overflow” che la CPU può impostare se il risultato è più grande dello spazio che può memorizzare un byte dei risultati. (Il bit “overflow” può essere spesso indicato con il nome abbreviato di “OF”. Si tratta di una “o” maiuscola, non di uno zero). Il software può controllare il valore di questo flag e notare il “problema”. Lavorare con questo bit è spesso gestito in modo invisibile da linguaggi di livello superiore, quindi i programmatori principianti spesso non imparano ad interagire con i flag della CPU. Tuttavia, i programmatori di assembly possono comunemente accedere ad alcuni di questi flag in modo molto simile ad altre variabili.

Per esempio, si potrebbero avere più istruzioni ADD. Un'istruzione ADD potrebbe memorizzare 16 bit di risultati nel registro A e nel registro D, mentre un'altra istruzione potrebbe semplicemente memorizzare gli 8 bit bassi nel registro A, ignorare il registro D e specificare il bit di overflow. Quindi, in seguito (dopo aver memorizzato i risultati del registro A nella RAM principale), si potrebbe utilizzare un'altra istruzione ADD che memorizza solo gli 8 bit alti in un registro (possibilmente il registro A.) L'eventuale necessità di utilizzare un flag di overflow può dipendere proprio da quale istruzione di moltiplicazione si utilizza.

(C'è anche comunemente un flag “underflow”, nel caso in cui si sottragga troppo per adattarsi al risultato desiderato)

Giusto per mostrarvi quanto complicate siano diventate le cose: L'Intel 4004 era una CPU a 4 bit L'Intel 8008 era una CPU a 8 bit. Aveva registri a 8 bit di nome A, B, C e D. L'Intel 8086 era una CPU a 16 bit. Aveva registri a 16 bit denominati AX, BX, CX e DX. L'Intel 80386 era una CPU a 32 bit. Aveva registri a 32 bit denominati EAX, EBX, ECX e EDX. Le CPU Intel x64 hanno registri a 64 bit denominati RAX, RBX, RCX e RDX. I chip x64 possono eseguire codice a 16 bit (in alcune modalità operative) e possono interpretare istruzioni a 16 bit. In questo modo, i bit che compongono il registro AX sono la metà dei bit che compongono il registro EAX, che sono la metà dei bit che compongono il registro RAX. Quindi, ogni volta che si cambia il valore di AX, si cambia anche EAX e RAX, perché i bit utilizzati da AX fanno parte dei bit utilizzati da RAX. (Se si cambia EAX di un valore che è un multiplo di 65.536, allora i 16 bit bassi sono invariati, quindi AX non cambierebbe. Se si cambia EAX di un valore che non è un multiplo di 65.536, allora anche questo influenzerebbe AX.)

Ci sono più flag e registri di quelli che ho menzionato. Ne ho semplicemente scelti alcuni di uso comune per fornire un semplice esempio concettuale.

Ora, se si è su una CPU a 8 bit, quando si scrive in memoria, si possono trovare alcune restrizioni sulla possibilità di fare riferimento a un indirizzo di 8 bit, non a un indirizzo di 4 bit o 16 bit. I dettagli variano in base alla CPU, ma se si hanno tali restrizioni, allora la CPU potrebbe avere a che fare con parole a 8 bit, ed è per questo che la CPU è più comunemente chiamata “CPU a 8 bit”.

Advertisement