Por qué 7 / 2 es igual a 3 en C++ (división entera)
Respuesta corta: cuando ambos operandos son enteros, C++ hace división entera — la parte fraccionaria se descarta, no se redondea. 7 / 2 es 3, -7 / 2 es -3 (truncamiento hacia cero) y 7 % 2 da el resto, 1.
Esto sorprende a casi todo el que llega con mentalidad de calculadora, y es el origen de una enorme parte de los bugs de principiante — medias rotas, porcentajes siempre en cero, conteos descuadrados. Ejecuta esto y lee línea por línea:
#include <iostream>
using namespace std;
int main() {
cout << "7 / 2 = " << 7 / 2 << endl; // 3 (se descarta la fracción)
cout << "7 % 2 = " << 7 % 2 << endl; // 1 (el resto)
cout << "7.0 / 2 = " << 7.0 / 2 << endl; // 3.5 (un operando es double)
int a = 7, b = 2;
cout << "(double)a/b = " << (double)a / b << endl; // 3.5 (¡convertir primero!)
cout << "(double)(a/b) = " << (double)(a / b) << endl; // 3 (tarde: ya se dividió como int)
return 0;
}
La regla, con precisión
El tipo de a / b se decide antes de dividir, a partir de los tipos de los operandos:
- int / int → int. El resultado se trunca hacia cero:
7/2 → 3,99/100 → 0. - Al menos un double/float → división de coma flotante.
7.0/2 → 3.5. Un solo punto decimal basta para cambiar el comportamiento. a % b(módulo) es el resto de esa misma división entera:7 % 2 → 1. Solo funciona con tipos enteros.
Las dos últimas líneas de la demo son el detalle de nivel entrevista: (double)a / b arregla el problema (la conversión ocurre antes de dividir), mientras que (double)(a / b) convierte un 3 ya truncado — los paréntesis lo deciden todo.
La forma moderna de convertir
La conversión estilo C, (double)a, funciona pero es un mazo. La forma preferida de C++ dice exactamente qué pasa:
double exact = static_cast<double>(a) / b; // 3.5
Mismo resultado, pero buscable, y no compila por accidente cuando querías otra cosa. (Nuestro motor del navegador cubre el núcleo didáctico y aún no soporta static_cast — pruébalo en tu compilador de escritorio.)
Negativos: truncar hacia cero, no «redondear hacia abajo»
Aquí los lenguajes discrepan, y es un punto de entrevista excelente. C++ trunca hacia cero:
-7 / 2 // -3 (hacia cero; Python daría -4)
7 / -2 // -3
-7 % 2 // -1 (el resto hereda el signo del dividendo)
El truncamiento de C++ toma la parte entera y le aplica el signo. Python, en cambio, redondea hacia menos infinito — mismas mates, convención distinta. Al portar código entre lenguajes, esto muerde.
Los tres bugs que causa en código real
- La media que siempre da cero:
sum / countcon dos int da0en cuantocount > sum. Solución:static_cast<double>(sum) / count. - El porcentaje que siempre da cero:
x / total * 100— la división va primero y trunca. Solución:100.0 * x / total(multiplicar primero) o convertir. - El bucle que corre una vez de más o de menos: aritmética tipo
for (int i = 0; i <= n; i += n/2)— connimpar, la división entera cambia el paso. Misma familia que los off-by-one de los bucles.
¿Redondear en lugar de truncar?
La división entera no redondea, pero puedes lograrlo: suma la mitad del divisor antes de dividir (para positivos), o convierte, suma 0.5 y vuelve a convertir:
int rounded = (a + b / 2) / b; // p. ej. 7/2 -> (7+1)/2 = 4
int rounded2 = (int)(7.0 / 2 + 0.5); // 4
Para código numérico serio, usa std::round de <cmath> en lugar de trucos caseros.
Preguntas de entrevista sobre el tema
- «¿Cuánto son
7 / 2y7 % 2?» —3y1; luego preguntan por los negativos (arriba). - «¿Por qué
100.0 * x / totaldifiere dex / total * 100?» — orden de evaluación; en la primera nunca hay int entre int. - «¿Se puede usar
%con doubles?» — no, solo enteros (para coma flotante,fmodde<cmath>). - «¿Para qué sirve
i % 2?» — par/impar, exactamente el truco decontinuede la guía de bucles.
Práctica en el editor
- Cambia la demo a
a = 100, b = 7y predice las cinco salidas antes de ejecutar. - Calcula la media de
1, 2mal y luego bien, y compara. - Imprime si cada número del 1 al 20 es par o impar con
%(bucles + división en un solo ejercicio).
Relacionado: for vs while, las 15 preguntas para juniors, y la lección del Hola Mundo si estás empezando.