C ++. Dividir 1 por cualquier número da 0

Cuando trato de dividir 1/60 o 1 / (60 * 60) da 0. Incluso en la ventana del depurador. Estoy un poco confundido de lo que podría ser, porque 2/3 o 2.5 / 6 dan resultados.

Mi código:

int main() { double k1 = 1/60; cout << k1 << endl; double k2 = 1/(60*60); cout << k2 << endl; return 0; } 

Aprecio tu ayuda.

Dado que ambos operandos son enteros, el comstackdor realiza una división entera (que no calcula la parte decimal). Si al menos uno de los operandos es un tipo de punto flotante (como en otros ejemplos), el otro se promueve y se realiza una división de punto flotante.

La solución

Cree al menos uno de los operandos de un tipo de punto flotante ( double o float ); Usted puede hacer esto, por ejemplo:

  • convirtiéndolo en un double literal 2 ( 60 es entero, 60.0 o incluso 60. es double , 60.f es float )
  • utilizando un molde ( double(60) , (double)60 ).

Personalmente, prefiero usar directamente literales double : no es que el reparto tenga ninguna penalización de rendimiento en comstackdores medio decentes, sino que se siente “mal” y detallado con respecto a solo usar un literal del tipo correcto. (Obviamente, cuando ambos operandos son variables y no literales, tienes que usar el reparto)

Objeciones comunes

  • “¡Pero lo estoy asignando a un double !”

    Este hecho confunde a muchos novatos, ya que creen que asignar 1 resultado a un double debería ser una especie de sugerencia para el comstackdor. De hecho, no lo es.

    Los cálculos / promociones realizados en la expresión son completamente independientes del tipo de destino, que es solo el último paso. Las subexpresiones se evalúan según lo que son, sin tener en cuenta cómo se usará el resultado, por lo que todas las promociones / operaciones de tipo dependen solo del tipo de los operandos.

  • ¿Por qué uno querría una división entera?

    Varios idiomas realizan automáticamente la división de punto flotante incluso cuando los argumentos son ambos enteros (por ejemplo, VB6, IIRC), ya que se siente más intuitivo para los principiantes. No es así en C / C ++: la división es integral cuando los argumentos son enteros, ya que en muchos casos simplemente no le importan los decimales, y es preferible, por razones de rendimiento, no usar la FPU (la filosofía de fondo en C y C ++ es “no paga por lo que no usa”).

    Obviamente, el problema podría haberse resuelto utilizando un operador separado para la división integral (VB, nuevamente, utiliza \ ), pero en mi humilde opinión tenemos suficientes operadores en C ++ como están. 🙂


  1. El rincón de Nitpickers: sí, aquí en realidad es una inicialización, no una tarea, pero estamos hablando del mismo tipo de idea errónea.
  2. Un “literal” es un valor incluido en el código fuente.

La línea double k1 = 1/60 será evaluada por el comstackdor como una constante de comstackción. Dado que no hay un ‘.0’ al final del número, 1/60 se evaluará mediante una división de enteros, y por lo tanto será 0.

El denominador también tiene que ser un número decimal.

 double k1 = 1/60.0; //Should work 

De lo contrario, su progtwig esencialmente truncará todos los decimales.

LITTLE EXTRA: Cuando tu denominador es una variable, debes lanzarlo:

 double k2 = 1/(double)myDenom;