Réponses:
Les deux opérandes (1 et 3) sont des entiers, par conséquent l'arithmétique entière (division ici) est utilisée. Déclarer la variable de résultat comme double provoque simplement une conversion implicite après la division .
La division entière renvoie bien sûr le vrai résultat de la division arrondie vers zéro. Le résultat de 0.333...
est donc arrondi à 0 ici. (Notez que le processeur ne fait aucun arrondi, mais vous pouvez toujours y penser de cette façon.)
Notez également que si les deux opérandes (nombres) sont donnés sous forme de flottants; 3.0 et 1.0, ou même juste le premier , puis l'arithmétique à virgule flottante est utilisée, vous donnant 0.333...
.
DOWN
est vers zéro. L'arrondi FLOOR
est vers l'infini négatif.
1/3
utilise la division entière car les deux côtés sont des entiers.
Vous avez besoin d'au moins l'un d'entre eux pour être float
ou double
.
Si vous entrez les valeurs dans le code source comme votre question, vous pouvez le faire 1.0/3
; l' 1.0
est double.
Si vous obtenez les valeurs ailleurs, vous pouvez les utiliser (double)
pour transformer le int
fichier double
.
int x = ...;
int y = ...;
double value = ((double) x) / y;
Tu devrais utiliser
double g=1.0/3;
ou
double g=1/3.0;
La division entière renvoie un entier.
Parce que vous faites une division entière.
Comme le dit @Noldorin, si les deux opérateurs sont des entiers, alors la division entière est utilisée.
Le résultat 0.33333333 ne peut pas être représenté comme un entier, donc seule la partie entière (0) est affectée au résultat.
Si l'un des opérateurs est un double
/ float
, alors l'arithmétique en virgule flottante aura lieu. Mais vous aurez le même problème si vous faites cela:
int n = 1.0 / 3.0;
Parce qu'il traite 1 et 3 comme des entiers, arrondissant donc le résultat à 0, de sorte que ce soit un entier.
Pour obtenir le résultat que vous recherchez, dites explicitement à java que les nombres sont des doubles comme ceci:
double g = 1.0/3.0;
La conversion en JAVA est assez simple mais nécessite une certaine compréhension. Comme expliqué dans le JLS pour les opérations sur les entiers :
Si un opérateur entier autre qu'un opérateur de décalage a au moins un opérande de type long, alors l'opération est effectuée avec une précision de 64 bits et le résultat de l'opérateur numérique est de type long. Si l'autre opérande n'est pas long, il est d'abord élargi (§5.1.5) pour taper long par promotion numérique (§5.6).
Et un exemple est toujours la meilleure façon de traduire le JLS;)
int + long -> long
int(1) + long(2) + int(3) -> long(1+2) + long(3)
Sinon, l'opération est effectuée avec une précision de 32 bits et le résultat de l'opérateur numérique est de type int. Si l'un des opérandes n'est pas un int, il est d'abord élargi pour taper int par promotion numérique.
short + int -> int + int -> int
Un petit exemple utilisant Eclipse pour montrer que même une addition de deux short
s ne sera pas si simple:
short s = 1;
s = s + s; <- Compiling error
//possible loss of precision
// required: short
// found: int
Cela nécessitera un moulage avec une perte de précision possible.
La même chose est vraie pour les opérateurs à virgule flottante
Si au moins l'un des opérandes d'un opérateur numérique est de type double, alors l'opération est effectuée en utilisant l'arithmétique à virgule flottante 64 bits, et le résultat de l'opérateur numérique est une valeur de type double. Si l'autre opérande n'est pas un double, il est d'abord élargi (§5.1.5) pour taper double par promotion numérique (§5.6).
La promotion se fait donc sur le flotteur en double.
Et le mélange de valeurs entières et flottantes donne des valeurs flottantes comme dit
Si au moins l'un des opérandes d'un opérateur binaire est de type à virgule flottante, alors l'opération est une opération à virgule flottante, même si l'autre est intégral.
Ceci est vrai pour les opérateurs binaires mais pas pour les "opérateurs d'affectation" comme +=
Un simple exemple de travail suffit à le prouver
int i = 1;
i += 1.5f;
La raison est qu'il y a un cast implicite fait ici, ce sera exécuté comme
i = (int) i + 1.5f
i = (int) 2.5f
i = 2
1 et 3 sont des nombres entiers et donc Java effectue une division entière dont le résultat est 0. Si vous voulez écrire des constantes doubles, vous devez écrire 1.0
et 3.0
.
La solution la plus simple est simplement de faire ceci
double g = ((double) 1 / 3);
Ce que cela fait, puisque vous n'avez pas entré 1.0 / 3.0, vous permet de le convertir manuellement en type de données double puisque Java a supposé qu'il s'agissait d'une division Integer, et il le ferait même si cela signifiait réduire la conversion. C'est ce qu'on appelle un opérateur de cast.
J'ai fait ça.
double g = 1.0/3.0;
System.out.printf("%gf", g);
Utilisez .0 tout en faisant des calculs doubles, sinon Java supposera que vous utilisez des nombres entiers. Si un calcul utilise une quantité de valeurs doubles, la sortie sera une valeur double. Si le sont tous des nombres entiers, alors la sortie sera un entier.
(1/3) signifie division entière, c'est pourquoi vous ne pouvez pas obtenir de valeur décimale à partir de cette division. Pour résoudre ce problème, utilisez:
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);
}
Étant donné que 1 et 3 sont des entiers, le résultat n'est pas arrondi mais tronqué. Vous ignorez donc les fractions et ne prenez que des entiers.
Pour éviter cela, utilisez au moins un de vos nombres 1 ou 3 sous forme décimale 1.0 et / ou 3.0.
Essayez ceci:
public static void main(String[] args) {
double a = 1.0;
double b = 3.0;
double g = a / b;
System.out.printf(""+ g);
}
Faites "double g = 1.0 / 3.0;" au lieu.
Beaucoup d'autres n'ont pas souligné le vrai problème:
Une opération sur uniquement des entiers convertit le résultat de l'opération en entier.
Cela signifie nécessairement que les résultats en virgule flottante, qui pourraient être affichés sous forme d'entier, seront tronqués (coupez la partie décimale).
Qu'est-ce que le casting (conversion de type / conversion de type) vous demandez-vous?
Cela varie selon l'implémentation du langage, mais Wikipédia a une vue assez complète, et il parle également de coercition , qui est une information essentielle pour répondre à votre question.
1/2
, pas dans la langue cible (java). Vous appelez simplement une division entière, qui se traduira par un résultat entier. La conversion de type est uniquement due à la conversion ascendante de int
en a double
pendant l'affectation.
0.5
. Simplement, en Java, 1/2
est une division entière, qui se traduit par un entier nul. Vous pouvez attribuer un zéro à un double, ce sera toujours un zéro, bien qu'un 0.0
double.
int i = .99999999
met int à 0. Plus spécifiquement, il prend la partie entière et rejette le reste.