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)

È stato utile?

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 chars 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 chars, 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 ??

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