Respuestas:
Los dos operandos (1 y 3) son números enteros, por lo tanto, se utiliza la aritmética de números enteros (división aquí). Declarar la variable de resultado como doble solo provoca una conversión implícita después de la división .
La división de enteros, por supuesto, devuelve el resultado real de la división redondeada hacia cero. Por tanto, el resultado de 0.333...
se redondea aquí a 0. (Tenga en cuenta que el procesador en realidad no realiza ningún redondeo, pero aún puede pensarlo de esa manera).
Además, tenga en cuenta que si ambos operandos (números) se dan como flotantes; 3.0 y 1.0, o incluso solo el primero , luego se usa aritmética de punto flotante, lo que le da 0.333...
.
DOWN
es hacia cero. El redondeo FLOOR
es hacia el infinito negativo.
1/3
usa la división de enteros ya que ambos lados son enteros.
Necesitas que al menos uno de ellos sea float
o double
.
Si está ingresando los valores en el código fuente como su pregunta, puede hacerlo 1.0/3
; el 1.0
es un doble.
Si obtiene los valores de otro lugar, puede usarlos (double)
para convertir el archivo int
en un double
.
int x = ...;
int y = ...;
double value = ((double) x) / y;
Deberías usar
double g=1.0/3;
o
double g=1/3.0;
La división de enteros devuelve un entero.
Porque estás haciendo una división de enteros.
Como dice @Noldorin, si ambos operadores son enteros, entonces se usa la división de enteros.
El resultado 0.33333333 no se puede representar como un número entero, por lo tanto, solo se asigna la parte entera (0) al resultado.
Si alguno de los operadores es double
/ float
, entonces se llevará a cabo la aritmética de punto flotante. Pero tendrás el mismo problema si haces eso:
int n = 1.0 / 3.0;
Porque trata 1 y 3 como números enteros, por lo tanto, redondea el resultado a 0, de modo que sea un número entero.
Para obtener el resultado que está buscando, dígale explícitamente a Java que los números son dobles así:
double g = 1.0/3.0;
La conversión en JAVA es bastante simple pero necesita algo de comprensión. Como se explica en el JLS para operaciones con números enteros :
Si un operador entero que no sea un operador de turno tiene al menos un operando de tipo long, entonces la operación se lleva a cabo con precisión de 64 bits y el resultado del operador numérico es de tipo long. Si el otro operando no es largo, primero se amplía (§5.1.5) para escribir largo mediante promoción numérica (§5.6).
Y un ejemplo es siempre la mejor manera de traducir el JLS;)
int + long -> long
int(1) + long(2) + int(3) -> long(1+2) + long(3)
En caso contrario, la operación se realiza con precisión de 32 bits y el resultado del operador numérico es de tipo int. Si alguno de los operandos no es un int, primero se amplía para escribir int mediante promoción numérica.
short + int -> int + int -> int
Un pequeño ejemplo que usa Eclipse para mostrar que incluso una adición de dos short
s no será tan fácil:
short s = 1;
s = s + s; <- Compiling error
//possible loss of precision
// required: short
// found: int
Esto requerirá una fundición con una posible pérdida de precisión.
Lo mismo es cierto para los operadores de punto flotante.
Si al menos uno de los operandos de un operador numérico es de tipo double, entonces la operación se realiza usando aritmética de coma flotante de 64 bits y el resultado del operador numérico es un valor de tipo double. Si el otro operando no es un doble, primero se amplía (§5.1.5) para escribir doble mediante promoción numérica (§5.6).
Entonces la promoción se hace en el flotador al doble.
Y la combinación de valores enteros y flotantes da como resultado valores flotantes como se dijo
Si al menos uno de los operandos de un operador binario es de tipo de coma flotante, entonces la operación es una operación de coma flotante, incluso si el otro es integral.
Esto es cierto para los operadores binarios, pero no para los "Operadores de asignación" como +=
Un simple ejemplo de trabajo es suficiente para probar esto.
int i = 1;
i += 1.5f;
La razón es que hay un reparto implícito hecho aquí, esto se ejecutará como
i = (int) i + 1.5f
i = (int) 2.5f
i = 2
La solución más sencilla es simplemente hacer esto
double g = ((double) 1 / 3);
Lo que hace esto, ya que no ingresó 1.0 / 3.0, es permitirle convertirlo manualmente al tipo de datos double ya que Java asumió que era una división de enteros, y lo haría incluso si significara reducir la conversión. Esto es lo que se llama operador de conversión.
Hice esto.
double g = 1.0/3.0;
System.out.printf("%gf", g);
Use .0 mientras hace cálculos dobles o de lo contrario Java asumirá que está usando Integers. Si un cálculo usa cualquier cantidad de valores dobles, entonces la salida será un valor doble. Si son todos enteros, la salida será un entero.
(1/3) significa división de números enteros, por eso no puede obtener un valor decimal de esta división. Para resolver este problema utilice:
public static void main(String[] args) {
double g = 1.0 / 3;
System.out.printf("%.2f", g);
}
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
Dado que tanto 1 como 3 son números enteros, el resultado no se redondea sino que se trunca. Entonces ignoras las fracciones y solo tomas enteros.
Para evitar esto, tenga al menos uno de sus números 1 o 3 como forma decimal 1.0 y / o 3.0.
Probar esto:
public static void main(String[] args) {
double a = 1.0;
double b = 3.0;
double g = a / b;
System.out.printf(""+ g);
}
Haga "doble g = 1.0 / 3.0;" en lugar.
Muchos otros no han logrado señalar el problema real:
Una operación solo con números enteros convierte el resultado de la operación en un número entero.
Esto necesariamente significa que los resultados de coma flotante, que podrían mostrarse como un número entero, se truncarán (recortar la parte decimal).
Que es casting (encasillado / conversión de tipo)?
Varía según la implementación del lenguaje, pero Wikipedia tiene una visión bastante completa y habla de coerción. , que es una pieza fundamental de información para responder a su pregunta.
1/2
, no en el idioma de destino (java). Simplemente invoca una división de enteros, que dará como resultado un resultado entero. La conversión de tipos se debe únicamente a la conversión ascendente de int
a a double
durante la asignación.
0.5
. Simplemente, en Java, 1/2
es una división de enteros, lo que resulta en un entero cero. Puede asignar un cero a un doble, seguirá siendo un cero, aunque sea un 0.0
doble.
int i = .99999999
establece int en 0. Más específicamente, toma la parte entera y descarta el resto.