División entera: ¿cómo se produce un doble?

Para este bloque de código:

int num = 5; int denom = 7; double d = num / denom; 

el valor de d es 0.0 . Se puede forzar a trabajar mediante casting:

 double d = ((double) num) / denom; 

¿Pero hay otra forma de obtener el double resultado correcto? No me gusta lanzar primitivos, quién sabe qué puede pasar.

 double num = 5; 

Eso evita un lanzamiento. Pero verás que las conversiones del elenco están bien definidas. No tienes que adivinar, solo revisa el JLS . int a double es una conversión cada vez más amplia. De §5.1.2 :

Las conversiones primitivas ampliadas no pierden información sobre la magnitud general de un valor numérico.

[…]

La conversión de un valor int o un valor largo en float, o de un valor largo en double, puede dar como resultado la pérdida de precisión, es decir, el resultado puede perder algunos de los bits menos significativos del valor. En este caso, el valor del punto flotante resultante será una versión redondeada correctamente del valor entero, utilizando el modo IEEE 754 redondeado a más cercano (§4.2.4) .

5 se puede express exactamente como un doble.

¿Qué pasa con los primitivos de casting?

Si no quieres lanzar por alguna razón, podrías hacer

 double d = num * 1.0 / denom; 

No me gusta lanzar primitivos, quién sabe qué puede pasar.

¿Por qué tienes un miedo irracional a lanzar primitivos? Nada malo sucederá cuando lanzas un int a un double . Si no está seguro de cómo funciona, búsquelo en la Especificación del lenguaje Java . Lanzar un int al double es una conversión primitiva que se está ampliando .

Puede deshacerse del par de paréntesis adicionales al convertir el denominador en lugar del numerador:

 double d = num / (double) denom; 

Si cambias el tipo de una de las variables, debes recordar colar un doble nuevamente si tu fórmula cambia, porque si esta variable deja de ser parte del cálculo, el resultado se arruina. Tengo el hábito de lanzar dentro del cálculo y agrego un comentario al lado.

 double d = 5 / (double) 20; //cast to double, to do floating point calculations 

Tenga en cuenta que lanzar el resultado no lo hará

 double d = (double)(5 / 20); //produces 0.0 

Eche uno de los enteros / ambos del entero para flotar para forzar la operación a realizarse con matemática de coma flotante. De lo contrario, las matemáticas enteras siempre son preferidas. Asi que:

 1. double d = (double)5 / 20; 2. double v = (double)5 / (double) 20; 3. double v = 5 / (double) 20; 

Tenga en cuenta que lanzar el resultado no lo hará. Porque la primera división se hace según la regla de precedencia.

 double d = (double)(5 / 20); //produces 0.0 

No creo que haya ningún problema con el casting, ya que estás pensando.

Tipo Casting es el único camino


Producir un double partir de una división entera: no hay otra forma sin lanzar (puede ser que no lo hagas explícitamente pero sucederá).

Ahora, hay varias maneras en que podemos tratar de obtener un valor double preciso (donde num y denom son int tipo y, por supuesto, con casting ) –

  1. con lanzamiento explícito:

    • double d = (double) num / denom;
    • double d = ((double) num) / denom;
    • double d = num / (double) denom;
    • double d = (double) num / (double) denom;

pero no double d = (double) (num / denom);

  1. con lanzamiento implícito:

    • double d = num * 1.0 / denom;
    • double d = num / 1d / denom;
    • double d = ( num + 0.0 ) / denom;
    • double d = num; d /= denom;

pero no double d = num / denom * 1.0;
y no double d = 0.0 + ( num / denom );

use algo como:

 double step = 1d / 5; 

(1d es un lanzamiento para doblar)

Puede considerar envolver las operaciones. Por ejemplo:

 class Utils { public static double divide(int num, int denom) { return ((double) num) / denom; } } 

Esto le permite buscar (solo una vez) si el elenco hace exactamente lo que quiere. Este método también podría estar sujeto a pruebas para garantizar que continúe haciendo lo que usted desea. Tampoco importa qué truco utilices para causar la división (puedes usar cualquiera de las respuestas aquí), siempre y cuando se obtenga el resultado correcto. En cualquier lugar donde necesite dividir dos enteros, ahora puede llamar a Utils::divide y confiar en que hace lo correcto.

solo usa esto.

 int fxd=1; double percent= (double)(fxd*40)/100; 

La mejor forma de hacerlo es

 int i = 3; Double d = i * 1.0; d is 3.0 now.