Moltiplicando char e int insieme in C parte 2
-
28-09-2019 - |
Domanda
Se faccio la seguente:
int c0 = CHAR_MAX; //8 bit
int c1 = CHAR_MAX; //8-bit
int i = c0*c1; //store in 32-bit variable
printf("%d\n", i); //prints 16129
Possiamo vedere che non v'è alcun problema di numeri a 8 bit moltiplicati insieme, e producendo un'uscita a 32 bit.
Tuttavia, se faccio
int i0 = INT_MAX; //32-bit
int i1 = INT_MAX; //32 bit variable
long long int ll = i0*i1; //store in 64-bit variable
printf("%lld\n", ll); //prints 1..overflow!!
In questo caso, due variabili a 32 bit sono stati moltiplicati insieme, traboccato, e poi sono stati assegnati alla variabile 64 bit.
Allora perché questo trabocco accadere quando moltiplicando gli interi, ma non i caratteri? E 'dipendente dal word-dimensione predefinita della mia macchina? (32 bit)
Soluzione
C'è un errore logico nella spiegazione di ciò che sta accadendo.
In almeno sistemi Linux, CHAR_MAX
di certo non è un numero a 8 bit. Si tratta di un preprocessore (più o meno) semplice definire, in questo modo:
# define SCHAR_MAX 127
/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */
# define UCHAR_MAX 255
/* Minimum and maximum values a `char' can hold. */
# ifdef __CHAR_UNSIGNED__
# define CHAR_MIN 0
# define CHAR_MAX UCHAR_MAX
# else
# define CHAR_MIN SCHAR_MIN
# define CHAR_MAX SCHAR_MAX
# endif
Quindi, per un sistema con char
s firmati, le ultime due righe sono a tutti gli effetti, il che significa che quando si scrive CHAR_MAX nel codice, il compilatore vede una pianura 127, che dispone di tipo int
.
Ciò significa che il CHAR_MAX
moltiplicazione * CHAR_MAX
avviene a precisione int
.
Altri suggerimenti
Si dovrebbe modificare il secondo esempio di codice come
int i0 = INT_MAX; //32-bit
int i1 = INT_MAX; //32 bit variable
long long ll = ((long long)i0)*i1; //compute and store in 64-bit variable
printf("%lld\n", ll);
che è, cast (almeno uno dei) i int a 64 bit di prima di loro moltiplicazione. Altrimenti l'overflow avviene perché il risultato è tentato di essere memorizzati in un temporaneo di tipo int
prima di assegnare alla variabile long long
. Il risultato di qualsiasi espressione viene colato alla precisione del suo membro con la massima precisione.
Nel primo esempio, un int
è abbastanza grande da contenere il risultato di moltiplicare char
s, quindi non c'è troppo pieno.
Come nota a margine, chiamare il vostro ll
variabile non è raccomandato in quanto è molto difficile distinguere tra la cifra '1' e la lettera minuscola 'l'.
Come funziona Typecast ...
A meno che non sia specificato typecast esplicito, qualsiasi espressione è typecasted alla precisione di alta precisione variabile / costante coinvolti.
Come Peter ha sottolineato, utilizzando un typecast esplicito nell'espressione di forze superiori precison.
Nota: non ho avuto il "long long int" parte. Forse è stato un molto tempo da quando ho visto uno ...; -)
- long long int davvero dichiarare una a 64 bit int ??
quale compilatore sono U con ??