Respostas:
Os dois operandos (1 e 3) são inteiros, portanto a aritmética de inteiros (divisão aqui) é usada. Declarar a variável de resultado como double apenas faz com que uma conversão implícita ocorra após a divisão .
A divisão inteira, é claro, retorna o verdadeiro resultado da divisão arredondado para zero. O resultado de 0.333...
é, portanto, arredondado para 0 aqui. (Observe que o processador não faz nenhum arredondamento, mas você ainda pode pensar nisso dessa forma.)
Além disso, observe que se ambos os operandos (números) são fornecidos como flutuantes; 3.0 e 1.0, ou mesmo apenas o primeiro , então a aritmética de ponto flutuante é usada, dando a você 0.333...
.
DOWN
é para zero. O arredondamento FLOOR
é em direção ao infinito negativo.
1/3
usa divisão inteira porque ambos os lados são inteiros.
Você precisa que pelo menos um deles seja float
ou double
.
Se você estiver inserindo os valores no código-fonte como sua pergunta, você pode fazer 1.0/3
; o 1.0
é um duplo.
Se você obtiver os valores de outro lugar, poderá usar (double)
para transformar o int
em a double
.
int x = ...;
int y = ...;
double value = ((double) x) / y;
você deveria usar
double g=1.0/3;
ou
double g=1/3.0;
A divisão inteira retorna um inteiro.
Porque você está fazendo uma divisão inteira.
Como @Noldorin diz, se ambos os operadores forem inteiros, então a divisão de inteiros é usada.
O resultado 0,33333333 não pode ser representado como um número inteiro, portanto, apenas a parte inteira (0) é atribuída ao resultado.
Se qualquer um dos operadores for um double
/ float
, a aritmética de ponto flutuante ocorrerá. Mas você terá o mesmo problema se fizer isso:
int n = 1.0 / 3.0;
Porque trata 1 e 3 como inteiros, portanto, arredondando o resultado para 0, de modo que seja um inteiro.
Para obter o resultado que você está procurando, diga explicitamente a java que os números são duplos, como:
double g = 1.0/3.0;
A conversão em JAVA é bastante simples, mas precisa de algum entendimento. Conforme explicado no JLS para operações inteiras :
Se um operador inteiro diferente de um operador de deslocamento tiver pelo menos um operando do tipo longo, a operação será realizada usando a precisão de 64 bits e o resultado do operador numérico será do tipo longo. Se o outro operando não for longo, ele é primeiro ampliado (§5.1.5) para digitar longo por promoção numérica (§5.6).
E um exemplo é sempre a melhor forma de traduzir o JLS;)
int + long -> long
int(1) + long(2) + int(3) -> long(1+2) + long(3)
Caso contrário, a operação é realizada com a precisão de 32 bits e o resultado do operador numérico é do tipo int. Se nenhum dos operandos for um int, ele é primeiro ampliado para o tipo int por promoção numérica.
short + int -> int + int -> int
Um pequeno exemplo usando Eclipse para mostrar que mesmo a adição de dois short
s não será tão fácil:
short s = 1;
s = s + s; <- Compiling error
//possible loss of precision
// required: short
// found: int
Isso exigirá uma fundição com uma possível perda de precisão.
O mesmo é verdadeiro para os operadores de ponto flutuante
Se pelo menos um dos operandos para um operador numérico for do tipo double, a operação será realizada usando aritmética de ponto flutuante de 64 bits e o resultado do operador numérico será um valor do tipo double. Se o outro operando não for um duplo, ele é primeiro ampliado (§5.1.5) para digitar duplo por promoção numérica (§5.6).
Portanto, a promoção é feita no float para o dobro.
E a mistura de valores inteiros e flutuantes resulta em valores flutuantes, como disse
Se pelo menos um dos operandos para um operador binário for do tipo de ponto flutuante, a operação será de ponto flutuante, mesmo se o outro for integral.
Isso é verdade para operadores binários, mas não para "Operadores de atribuição" como +=
Um exemplo simples de trabalho é o suficiente para provar isso
int i = 1;
i += 1.5f;
A razão é que há um elenco implícito feito aqui, ele será executado como
i = (int) i + 1.5f
i = (int) 2.5f
i = 2
A solução mais fácil é apenas fazer isso
double g = ((double) 1 / 3);
O que isso faz, uma vez que você não inseriu 1.0 / 3.0, é permitir que você o converta manualmente para o tipo de dados double, já que Java assumiu que era uma divisão inteira, e faria isso mesmo que significasse estreitar a conversão. Isso é chamado de operador de elenco.
Eu fiz isso.
double g = 1.0/3.0;
System.out.printf("%gf", g);
Use .0 ao fazer cálculos duplos ou então o Java assumirá que você está usando números inteiros. Se um cálculo usar qualquer quantidade de valores duplos, a saída será um valor duplo. Se forem todos inteiros, a saída será um inteiro.
(1/3) significa divisão inteira, por isso você não pode obter o valor decimal desta divisão. Para resolver este problema, use:
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);
}
Como 1 e 3 são inteiros, o resultado não é arredondado, mas truncado. Assim, você ignora as frações e pega apenas todos.
Para evitar isso, tenha pelo menos um de seus números 1 ou 3 como formato decimal 1.0 e / ou 3.0.
Experimente isto:
public static void main(String[] args) {
double a = 1.0;
double b = 3.0;
double g = a / b;
System.out.printf(""+ g);
}
Faça "duplo g = 1,0 / 3,0;" em vez de.
Muitos outros não conseguiram apontar o verdadeiro problema:
Uma operação apenas em inteiros converte o resultado da operação em um inteiro.
Isso necessariamente significa que os resultados de ponto flutuante, que podem ser exibidos como um inteiro, serão truncados (corte da parte decimal).
O que é casting (typecasting / conversão de tipo), você pergunta?
Isso varia de acordo com a implementação da linguagem, mas a Wikipedia tem uma visão bastante abrangente e também fala sobre coerção , que é uma informação essencial para responder à sua pergunta.
1/2
, não na linguagem de destino (java). Você simplesmente invoca uma divisão inteira, que resultará em um resultado inteiro. A Fundição de Tipo é apenas por causa da conversão ascendente de int
para a double
durante a atribuição.
0.5
. Simplesmente, em Java, 1/2
é uma divisão inteira, que resulta em um inteiro zero. Você pode atribuir um zero a um duplo, ainda será um zero, embora seja um 0.0
duplo.
int i = .99999999
define int como 0. Mais especificamente, ele pega a parte inteira e descarta o resto.