residuo - División de enteros en Java
operacion con decimales java (7)
Como lo explica el JLS , la operación entera es bastante simple.
Si un operador entero distinto de un operador de desplazamiento tiene al menos un operando de tipo largo, entonces la operación se lleva a cabo utilizando una precisión de 64 bits, y el resultado del operador numérico es de tipo largo. Si el otro operando no es largo, primero se amplía (§5.1.5) para escribir largo por promoción numérica (§5.6).
De lo contrario, la operación se lleva a cabo utilizando una precisión de 32 bits, y el resultado del operador numérico es de tipo int. Si ninguno de los operandos es un int, primero se amplía para escribir int por promoción numérica.
Entonces, para abreviar, una operación siempre daría como resultado un int
con la única excepción de que tiene un valor long
.
int = int + int
long = int + long
int = short + short
Tenga en cuenta que la prioridad del operador es importante, así que si tiene
long = int * int + long
la operación int * int
daría como resultado un int
, se promovería en un long
durante la operación int + long
Esta pregunta ya tiene una respuesta aquí:
- ¿Por qué es el resultado de 1/3 == 0? 13 respuestas
Esta es una pregunta básica, pero no puedo encontrar una respuesta. He analizado la aritmética de punto flotante y algunos otros temas, pero nada parecía abordar esto. Estoy seguro de que tengo la terminología equivocada.
Básicamente, quiero tomar dos cantidades, completas y totales, y dividirlas para obtener un porcentaje (de cuánto se ha completado). Las cantidades son long
s. Aquí está la configuración:
long completed = 25000;
long total = 50000;
System.out.println(completed/total); // Prints 0
Intenté reasignar el resultado a un doble: imprime 0.0
. ¿Dónde estoy equivocado?
Dicho sea de paso, el siguiente paso es multiplicar este resultado por 100, lo que supongo que será fácil una vez que este pequeño obstáculo haya sido pisado.
Por cierto, no es tarea aquí simplemente viejo numskull-ness (y tal vez demasiada codificación hoy).
Como su salida da como resultado un doble, debe convertir la variable completada o la variable total, o ambas, en dobles durante la división.
Entonces, la implementación correcta será:
System.out.println((double)completed/total);
Convertir la salida es demasiado tarde; el cálculo ya ha tenido lugar en aritmética de enteros. Necesita convertir las entradas a double
:
System.out.println((double)completed/(double)total);
Tenga en cuenta que en realidad no necesita convertir ambos ; mientras uno sea double
, el otro se convertirá implícitamente. Pero prefiero hacer ambas cosas, por simetría.
Convierta tanto el completed
como el total
en double
o al menos márquelos al double
al hacer la devision. Es decir, arrojar los varaibles para duplicar no solo el resultado.
Advertencia razonable, hay un problema de precisión de punto flotante cuando se trabaja con float
y double
.
Ni siquiera necesitas dobles para esto. Simplemente multiplique por 100 primero y luego divida. De lo contrario, el resultado sería menor que 1 y se truncaría a cero, como viste.
editar: o si es probable un desbordamiento, si se desborda (es decir, el dividendo es mayor que 922337203685477581), divida primero el divisor entre 100.
Si no echas explícitamente uno de los dos valores a un float antes de hacer la división, entonces se usará una división entera (así que es por eso que obtienes 0). Solo necesita que uno de los dos operandos sea un valor de coma flotante, de modo que se use la división normal (y otro valor entero se convierta automáticamente en un flotante).
Solo prueba con
float completed = 50000.0f;
y estará bien.
In Java
Integer/Integer = Integer
Integer/Double = Double//Either of numerator or denominator must be floating point number
1/10 = 0
1.0/10 = 0.1
1/10.0 = 0.1
Simplemente escriba "cast" cualquiera de ellos.