decimales - division java
División entera: ¿Cómo se produce un doble? (10)
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 obligar a trabajar por fundición:
double d = ((double) num) / denom;
¿Pero hay otra manera de obtener el resultado double
correcto? No me gustan los primitivos de casting, quién sabe qué puede pasar.
No me gustan los primitivos de casting, quién sabe qué puede pasar.
¿Por qué tienes un miedo irracional de lanzar primitivos? Nada malo pasará cuando lances un int
a un double
. Si no está seguro de cómo funciona, búsquelo en la JLS . Lanzar un int
para double
es una §5.1.2 .
Puedes deshacerte del par de paréntesis extra al usar el denominador en lugar del numerador:
double d = num / (double) denom;
Tipo Casting es la única manera
Producir un double
partir de la división entera: no hay otra forma sin casting (puede ser que no lo harás explícitamente, pero sucederá).
Ahora, hay varias maneras en que podemos tratar de obtener un valor double
preciso (donde num
y denom
son tipo int
y, por supuesto, con casting ) -
con casting 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);
con casting 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 );
¿Qué hay de malo con los primitivos de fundición?
Si no quieres lanzar por alguna razón, podrías hacerlo.
double d = num * 1.0 / denom;
Convierta uno de los enteros / ambos enteros a flotar para forzar que la operación se realice con matemática de coma flotante. De lo contrario, siempre se prefiere la matemática entera. 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 realiza según la regla de precedencia.
double d = (double)(5 / 20); //produces 0.0
No creo que haya ningún problema con el casting como el que estás pensando.
La mejor manera de hacer esto es
int i = 3;
Double d = i * 1.0;
d is 3.0 now.
Podría considerar envolver las operaciones. Por ejemplo:
class Utils
{
public static double divide(int num, int denom) {
return ((double) num) / denom;
}
}
Esto le permite consultar (solo una vez) si el reparto 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 el truco que uses para causar la división (puedes usar cualquiera de las respuestas aquí), siempre y cuando el resultado sea el correcto. En cualquier lugar donde necesite dividir dos enteros, ahora puede simplemente llamar a Utils::divide
y confiar en que hace lo correcto.
Si cambia el tipo de una, las variables que debe recordar para volver a introducirlas de nuevo si su fórmula cambia, porque si esta variable deja de ser parte del cálculo, el resultado se desordena. Hago un 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
solo usa esto
int fxd=1;
double percent= (double)(fxd*40)/100;
usa algo como
double step = 1d / 5;
(1d es un elenco para doblar)
double num = 5;
Eso evita un reparto. Pero encontrarás que las conversiones de reparto están bien definidas. No tienes que adivinar, solo revisa el JLS . Int de duplicar es una conversión de ampliación. A partir del §5.1.2 :
La ampliación de las conversiones primitivas no pierde información sobre la magnitud global de un valor numérico.
[...]
La conversión de un valor int o de un valor largo a flotante, o de un valor largo a duplicado, puede resultar en una pérdida de precisión, es decir, el resultado puede perder algunos de los bits menos significativos del valor. En este caso, el valor de punto flotante resultante será una versión correctamente redondeada del valor entero, utilizando el modo redondeado IEEE 754 (§4.2.4) .
5 se puede expresar exactamente como un doble.