Perché ci sono così tanti tipi numerici (bit, int, float, double, long)?

9

Ho imparato PHP, Java e C. Ora sono curioso del perché ci siano così tanti tipi di tipi di dati numerici come bit, int, float, double e long. Perché non creare un solo tipo per i numeri?

C'è qualche vantaggio in questo? Forse se usiamo numeri interi per contenere numeri così piccoli possiamo risparmiare memoria?

    
posta GusDeCooL 25.05.2013 - 06:32
fonte

7 risposte

16

Ci sono due ragioni per le quali dovresti preoccuparti dei diversi tipi di dati numerici.

1. Salvataggio della memoria

for(long k=0;k<=10;k++)
{
    //stuff
}

Perché usare un lungo quando potrebbe essere altrettanto facilmente un numero intero, o anche un byte? In questo modo risparmierai parecchi byte di memoria.

2. I numeri in virgola mobile e i numeri interi sono memorizzati in modo diverso nel computer

Supponiamo di avere il numero 22 memorizzato in un numero intero. Il computer memorizza questo numero in memoria in binario come:

0000 0000 0000 0000 0000 0000 0001 0110

Se non hai familiarità con il sistema dei numeri binari, questo può essere rappresentato nella notazione scientifica come: 2 ^ 0 * 0 + 2 ^ 1 * 1 + 2 ^ 2 * 1 + 2 ^ 3 * 0 + 2 ^ 4 * 1 + 2 ^ 5 * 0 + ... + 2 ^ 30 * 0. L'ultimo bit può o non può essere utilizzato per indicare se il numero è negativo (a seconda che il tipo di dati sia firmato o non firmato).

Essenzialmente, è solo una somma del valore 2 ^ (bit place) *.

Questo cambia quando ti riferisci a valori che coinvolgono un punto decimale. Supponiamo di avere il numero 3.75 in decimale. Si parla di 11.11 in binario. Possiamo rappresentare questo come una notazione scientifica come 2 ^ 1 * 1 + 2 ^ 0 * 1 + 2 ^ -1 * 1 + 2 ^ -2 * 1 o, normalizzata, come 1.111 * 2 ^ 2

Tuttavia, il computer non può memorizzarlo: non ha un metodo esplicito per esprimere quel punto binario (la versione del sistema di numeri binari del punto decimale). Il computer può solo memorizzare 1 e 0. Qui è dove arriva il tipo di dati in virgola mobile.

Supponendo che sizeof (float) sia 4 byte, allora hai un totale di 32 bit. Al primo bit viene assegnato il "bit di segno". Non ci sono galleggianti o doppi senza segno. Gli 8 bit successivi sono usati per "esponente" e gli ultimi 23 bit sono usati come "significando" (oa volte indicato come mantissa). Usando il nostro esempio 3.75, il nostro esponente sarebbe 2 ^ 1 e il nostro significato e sarebbe 1.111.

Se il primo bit è 1, il numero è negativo. In caso contrario, positivo. L'esponente viene modificato da qualcosa chiamato "il pregiudizio", quindi non possiamo semplicemente memorizzare "0000 0010" come esponente. Il bias per un singolo numero in virgola mobile di precisione è 127 e il bias per una precisione doppia (questo è il punto in cui il doppio tipo di dati ottiene il suo nome) è 1023. Gli ultimi 23 bit sono riservati per il significato. Il significato e semplicemente i valori a DESTRA del nostro punto binario.

Il nostro esponente sarebbe il bias (127) + esponente (1) o rappresentato in binario

1000 0000

Il nostro significato e sarebbe:

111 0000 0000 0000 0000 0000

Pertanto, 3,75 è rappresentato come:

0100 0000 0111 0000 0000 0000 0000 0000

Ora, diamo un'occhiata al numero 8 rappresentato come numero in virgola mobile e come numero intero:

0100 0001 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 1000

In che modo il mondo aggiungerà 8.0 e 8? O addirittura moltiplicarli !? I computer (in particolare i computer x86) hanno parti diverse della CPU che aggiungono numeri in virgola mobile e numeri interi.

    
risposta data 25.05.2013 - 07:46
fonte
6

Di nuovo prima che avessimo sistemi di gigabyte (o su sistemi embedded moderni come Arduino), la memoria era ad un livello premium e quindi sono stati implementati metodi abbreviati per specificare la quantità di memoria occupata da un determinato numero - BIT è semplice - occuperebbe originariamente solo 1 bit di memoria.

Le altre dimensioni e nomi dei dati variano a seconda dei sistemi. Su un sistema a 32 bit, INT (o MEDIUMINT) sarebbero generalmente 2 byte, LONGINT sarebbe 4 byte e SMALLINT sarebbe un singolo byte. I sistemi a 64 bit possono avere LONGINT impostato su 8 byte.

Anche ora - specialmente nelle applicazioni di database, o programmi che hanno più istanze in esecuzione su server (come script lato server sui siti Web) - si dovrebbe fare attenzione a ciò che si sceglie. Scegliere un intero di 2, 4 o 8 byte per memorizzare valori compresi tra 0 e 100 (che possono essere contenuti in un byte) è incredibilmente dispendioso se si dispone di una tabella di database con milioni di record.

Altre informazioni: link

    
risposta data 25.05.2013 - 07:36
fonte
4

Oltre agli eccellenti punti di cpmjr123 sulla scarsità di memoria e la precisione e la gamma di trade off, anche questo è potenzialmente un compromesso tra CPU.

La maggior parte delle macchine moderne ha hardware speciale per eseguire operazioni in virgola mobile chiamate FPU. Ci sono anche sistemi che non hanno FPU (al giorno d'oggi questi sono in genere piccoli dispositivi incorporati), di conseguenza, a seconda dell'hardware di destinazione, non dovresti utilizzare affatto i tipi a virgola mobile o utilizzare una libreria mobile in virgola mobile. Anche se la tua macchina ha una FPU ci sono storicamente differenze nelle funzioni che potrebbe fornire. Qualsiasi funzione non eseguita nell'hardware dovrebbe essere eseguita nel software (o evitata)

Effettuare calcoli in virgola mobile nel software avviene eseguendo molte operazioni più semplici supportate dall'hardware. Quindi ottieni anche un potenziale scambio di velocità.

    
risposta data 25.05.2013 - 08:35
fonte
4

Forse la cosa più importante è che ci sono davvero tre diversi tipi di numeri di base.

intero, decimale fisso e virgola mobile.

Si comportano tutti in modo diverso.

Una semplice operazione come 7/2 potrebbe dare risposte di 3, 3.50 e 3.499 a seconda del tipo di dati utilizzato.

"decimale fisso" è il tipo Cenerentola, è supportato solo in modo nativo in alcune lingue come COBOL e VisualBasic. È di scarso interesse per gli informatici ma è di vitale importanza per chiunque invii una serie di conti o calcoli l'imposta sulle vendite su una fattura.

    
risposta data 25.05.2013 - 11:06
fonte
3

Is there any benefit they make it?

Naturalmente. Ci sono benefici. Nel mondo dei computer la memoria è una delle cose più importanti da considerare. A che cosa serve avere una memoria di 2kb quando i dati possono essere contenuti in meno di 1kb? . Le ottimizzazioni dovrebbero essere lì. Se usi più memoria, ovviamente uccide la velocità del tuo computer in un punto. Ti piace davvero averlo? Non hai ragione ...?

int - 2 bytes (16 bits)

long - 4 bytes (32 bits)

long long - 8 bytes (64 bits)

float - 4 bytes

Non solo la memoria ma anche l'organizzazione del tipo di numeri. per un punto in virgola mobile. La precisione conta molto e ovviamente dovremmo avere un tipo che può darci più precisione.

Se consideriamo i tempi antichi, avevamo una memoria molto meno importante di quanto potresti sapere. Per salvarlo e usarlo saggiamente abbiamo avuto queste differenze. E molto altro se vai avanti e prova a cercare con google .. Spero che questo aiuti.

    
risposta data 25.05.2013 - 07:39
fonte
2

numeri interi e numeri reali (float, double) sono tipi concettualmente diversi con diversi insiemi di operazioni e proprietà intrinseche.

I numeri interi sono enumerabili ma i valori non sono, ecc.

Infatti Float / double number è una struttura che combina due campi interi: mantissa ed esponente. I numeri complessi (che hai escluso dalla considerazione) sono ancora più, beh, complessi.

Qualsiasi linguaggio pratico dovrebbe avere almeno numeri interi e caratteri mobili come tipi distinti: operazioni troppo diverse su di essi.

    
risposta data 25.05.2013 - 08:04
fonte
-1

Oltre al fatto che i tipi a virgola mobile si comportano in modo completamente diverso dai tipi interi, voglio dare un esempio più estremo perché la dimensione per numero è davvero importante.

Immagina di voler ordinare una matrice (lunga). Ad esempio in C:

int numbers[100000000];

Quindi qui abbiamo 100 milioni di numeri.

Se ogni numero è lungo solo un byte (quindi usando unsigned char invece di int ), allora questo richiede 100 milioni di byte di spazio.

Se utilizzi double , di solito sono 8 byte per numero, quindi 800 milioni di byte di spazio.

Quindi ogni volta che operi con molto di oggetti (numeri in questo esempio), le dimensioni per oggetto (dimensioni per numero in questo esempio) sono davvero importanti.

    
risposta data 25.05.2013 - 20:24
fonte

Leggi altre domande sui tag