2012-09-02 25 views
10

En C, ¿hay alguna diferencia entre la división entera a/b y el piso (a/b) donde tanto a como b son números enteros? Más específicamente, ¿qué sucede durante ambos procesos?C división entera y piso

Respuesta

11

a/b hace división entera. Si a o b es negativo, el resultado depende del compilador (el redondeo puede ir hacia cero o hacia el infinito negativo en pre-C99, en C99 +, el redondeo va hacia 0). El resultado tiene el tipo int. floor(a/b) hace la misma división, convierte el resultado en doble, descarta la parte fraccional (inexistente) y devuelve el resultado como un doble.

+2

En C, la división entera realiza el truncamiento hacia cero. Esto es cierto desde C99, antes de que se definiera su implementación. – ouah

+0

Ah, se perdió la etiqueta 'C'. Aún así, está claro que mi respuesta es sobre C++. '' –

+0

@Mysticial El punto es que 'floor' no redondea nada en este caso porque' a/b' realiza una división de enteros y * luego * lo pasa a 'floor'. – oldrinb

6

floor devuelve un double mientras a/b donde ambos a y b son números enteros produce un valor entero.

Con la conversión correcta, el valor es el mismo.

Si existía typeof operador en C (no) tendríamos:

(typeof (a /b)) floor(a/b) == a/b 

EDIT: Ahora bien, si la pregunta es: ¿hay alguna diferencia entre:

(double) (a/b) 

y

floor(a/(double) b) 

la respuesta es sí. Los resultados difieren con respecto a los valores negativos.

4

Es posible perder información convirtiendo de un número entero a coma flotante. No es probable con int y doble, pero con una ligera alteración:

#include <stdio.h> 
#include <math.h> 

int main(void) 
{ 
    unsigned long long a = 9000000000000000003; 
    unsigned long long b = 3; 
    printf("a/b = %llu\n", a/b); 
    printf("floor(a/b) = %f\n", floor(a/b)); 
    return 0; 
} 

Resultado:

a/b = 3000000000000000001 
floor(a/b) = 3000000000000000000.000000 
+1

Un double puede almacenar exactamente todos los valores enteros de 32 bits. Siempre puedes usar double en lugar de int. No es poco probable perder precisión, es imposible. Su ejemplo es correcto, pero engaña a las personas que aún no comprenden el problema. – maxy

1

En general, suponiendo que los números enteros son representable tanto en el número entero y los tipos de punto flotante, hay ISN No hay diferencia, pero la prueba no es obvia. El problema es que en punto flotante, se produce un redondeo en la división a/b, de modo que la función de piso no se aplica en el valor racional exacto, sino en un valor aproximado. Escribí un artículo sobre el tema: https://www.vinc17.net/research/publi.html#Lef2005b

En resumen, el resultado que obtuve es que si a - b es exactamente representable en el sistema de coma flotante, entonces piso (a/b), donde a y b son números flotantes (con valores enteros), da el mismo resultado que la división entera a/b.