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
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.
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.
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
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
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.
- 1. División entera en comparación con el cociente de piso: ¿por qué este sorprendente resultado?
- 2. división entera en php
- 3. La división entera siempre cero
- 4. División entera en Common Lisp?
- 5. La división entera en Python
- 6. ¿Cómo obtener fracciones en una división entera?
- 7. Redondeo de división entera con negativos en C++
- 8. División entera vs división flotante -> ¿Quién es responsable de proporcionar el resultado?
- 9. Float es 0 después de la división entera
- 10. MATLAB - pregunta de piso
- 11. C++ rápida división/mod por 10^x
- 12. /euclidiana número entero división de la división
- 13. División doble en C
- 14. Usar enum como constante entera en C#
- 15. CGFloat: redondo, piso, abs y precisión de 32/64 bit
- 16. Números aleatorios y función de piso contra redondo
- 17. Resolviendo la mochila entera
- 18. ¿Por qué el código de división entera da la respuesta incorrecta?
- 19. ¿Cómo se hace una división entera (firmada o no) en ARM?
- 20. lectura y la escritura matriz entera parcelar
- 21. división y concatenar una cadena
- 22. División y puntos flotantes
- 23. División de matrices en C++
- 24. matriz entera inicialización estática
- 25. C# problema de división sencilla
- 26. C++ - tipo de la división?
- 27. División de cadenas en C++
- 28. de estilo Python división de enteros y módulo en C
- 29. Multi-columna entera pedidos
- 30. java Referencia entera
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
Ah, se perdió la etiqueta 'C'. Aún así, está claro que mi respuesta es sobre C++. '' –
@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