2011-01-31 14 views
5

Sé que al dividir enteros, la forma predeterminada en que funciona es descartar la parte fraccionaria. Por ejemplo,Dividir enteros

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); 

El código anterior imprime:

N = 0 
Calls = 1 

Podría explicar este comportamiento?

+3

No lo entiendo, ¿no respondió su pregunta en la primera oración? –

+0

¿Podría * usted * explicar lo que piensa que es notable acerca de este comportamiento? –

+0

Creo que encontrará mi respuesta suficiente. –

Respuesta

14

1 dividido por 3 = .3333 (repitiendo por supuesto), matemáticamente. Puede pensar que la computadora trunca el .3333 dado que está haciendo una aritmética entera (0, resto 1).

El ciclo for se ejecuta porque i = 1 y 1 > 0. Después de ejecutar el cuerpo del bucle, divide i por tres y i se convierte en 0, que no es mayor que 0.

+3

@mizo: No, la condición se verifica antes de que se ingrese el cuerpo por primera vez. Si establece 'i = -1;' en la primera parte de la instrucción 'for', entonces el cuerpo del ciclo se omitirá por completo. –

+1

+1 para geeky referencia WoW. Supongo que podría haber hecho +1 por estar correcto, pero, diablos. 6 otros ya lo hicieron. :) –

+0

@James, tienes razón. Se eliminó el comentario incorrecto :) – mizo

1

Porque ejecuta el bucle una vez.

El incremento de bucle en for se ejecuta después de el cuerpo del bucle, y en la entrada de bucle i > 0 es cierto como 1 > 0, en se produce la siguiente división de bucle y entonces la prueba se convierten en la salida falsa y bucle.

3

reescribe como while y se vuelve evidente.

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

Todo es muy simple.

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); 

Espero que esto ayude.

+0

@James tiene razón, he editado mi respuesta. –

+0

No estoy seguro de entender su comentario con respecto al incremento pre vs post. Como no está capturando el retorno de la operación de incremento, ¿qué problema tiene cambiarlo a una corrección de incremento previo? –

+0

Toda la parte de incremento pre/post no tiene ninguna relevancia para el comportamiento. El cuerpo del ciclo se ejecuta una vez. Eso es todo lo que importa. –

1

¿Dónde está el problema? La primera línea de salida es inmediata: 1/3 = 0.33333 ..., eliminando la parte fraccionaria es 0.

Para la segunda línea, tenga en cuenta que el ciclo for se traduce a algo como esto:

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

Por lo tanto, al inicio i es 1; la primera iteración del while se ejecuta porque i, siendo 1, es mayor que 0. calls es 0 y se incrementa en 1, por lo tanto, obtiene 1. i se divide por 3, por lo que llega a 0 (porque la parte fraccionaria es no calculado en la división de enteros). La verificación de condición while se realiza nuevamente, pero ahora i es 0, por lo que el ciclo no se repite. calls permanece en 1 y este valor se imprime en la pantalla.

0

n es un entero, una división devolverá un número entero y no se doble o flotar

0

Debido a que en la aritmética de enteros, la respuesta a 1 dividido por 3 es 0 con un resto de 1. Si se divide dos números enteros, obtienes aritmética de enteros. Si desea aritmética de coma flotante, necesita al menos uno de los operandos para ser un valor de coma flotante.