2011-01-31 25 views
5

So che quando si dividono gli interi il modo predefinito in cui funziona è quello di scartare la parte frazionaria. Per esempio,Dividere i numeri interi

int i, n, calls = 0; 
n = 1; 
n /= 3; 
printf("N = %i\n", n); 
for (i = 1; i > 0; i /= 3) { 
    calls++; 
} 
printf("Calls = %i\n", calls); 

Il codice sopra stampe:

N = 0 
Calls = 1 

Potrebbe spiegare questo comportamento?

+3

Non capisco, non hai risposto alla tua domanda nella prima frase? –

+0

Potrebbe * tu * per favore spiegare cosa pensi che sia notevole di questo comportamento? –

+0

Penso che troverai la mia risposta sufficiente. –

risposta

14

1 diviso per 3 = .3333 (ripetuto ovviamente), matematicamente. Si può pensare al computer come a troncare il .3333 dato che sta eseguendo l'aritmetica dei numeri interi (0 il resto 1).

Il ciclo for viene eseguito perché i = 1 e 1 > 0. Dopo aver eseguito il corpo del ciclo, dividi i per tre e i diventa 0, che non è maggiore di 0.

+3

@mizo: No, la condizione viene verificata prima che il corpo venga inserito per la prima volta. Se imposti 'i = -1;' nella prima parte dell'istruzione 'for', il corpo del ciclo verrà saltato interamente. –

+1

+1 per riferimento a WoW geek. Suppongo che avrei potuto fare +1 per essere corretto, ma diamine. Altri 6 lo hanno già fatto. :) –

+0

@James, hai ragione. Commento errato rimosso :) – mizo

1

Perché esegue il ciclo una volta.

L'incremento loop for viene eseguito dopo corpo del ciclo, e all'entrata ciclo i > 0 è vero come 1 > 0, sulla verifica il successivo ciclo di divisione e quindi il test diventa falsa e ciclo uscita.

3

riscrivi come while e diventa evidente.

i = 1; 
while (i > 0) 
{ 
    calls++;   
    i /= 3; //This becomes .3333, which truncates to zero 
} 
-2

È tutto molto semplice.

int i, n, calls = 0; // Set calls to 0 
n = 1;    // n is now 1 
n /= 3;    // n /= 3 = 1/3 = 0 
printf("N = %i\n", n); 
for (i = 1; i > 0; i /= 3) { // 1/3 = 0 
    calls++;     // runs once 
}        
printf("Calls = %i\n", calls); 

Spero che questo aiuti.

+0

@James hai ragione, ho modificato la mia risposta. –

+0

Non sono sicuro di aver compreso il tuo commento relativo all'incremento pre vs post. Dal momento che non sta acquisendo il ritorno dell'operazione di incremento, quale problema lo modifica alla correzione pre-incremento? –

+0

L'intera parte di pre/post incremento non ha alcuna rilevanza per il comportamento. Il corpo del loop viene eseguito una volta. Questo è tutto ciò che conta. –

1

Dov'è il problema? La prima linea di uscita è immediata: 1/3 = 0,33333 ..., eliminando la parte frazionaria è 0.

Per la seconda linea di tenere presente che il ciclo for è tradotto in qualcosa di simile:

i=1; 
while(i>0) 
{ 
    calls++; 
    i/=3; 
} 

Quindi, all'inizio i è 1; la prima iterazione di while viene eseguita perché i, essendo 1, è maggiore di 0. calls è 0 e viene incrementato di 1, quindi arriva a 1. i è diviso per 3, quindi diventa 0 (perché la parte frazionaria è non calcolato nella divisione intera). Il controllo delle condizioni while viene eseguito di nuovo, ma ora i è 0, quindi il ciclo non viene ripetuto. calls rimane su 1 e questo valore viene stampato sullo schermo.

0

n è un int, una divisione restituirà un numero intero e nessun doppio o galleggiante

0

Perché in aritmetica intera, la risposta a 1 diviso per 3 è 0 con resto di 1. Se si divide due numeri interi, ottieni l'intero aritmetico. Se si desidera l'aritmetica in virgola mobile, è necessario che almeno uno degli operandi sia un valore in virgola mobile.

Problemi correlati