Division des entiers en Java [dupliquer]
Cette question a déjà une réponse ici:
- Pourquoi le résultat de 1/3 == 0? 13 réponses
C'est une question de base mais je ne trouve pas de réponse. J'ai examiné l'arithmétique à virgule flottante et quelques autres sujets, mais rien ne semble aborder cela. Je suis sûr que j'ai juste la mauvaise terminologie.
Fondamentalement, je veux en prendre deux quantités-complétées et totales-et divisez-les pour obtenir un pourcentage (de combien a été complété). Les quantités sont long
. s. Voici la configuration:
long completed = 25000;
long total = 50000;
System.out.println(completed/total); // Prints 0
J'ai essayé de réaffecter le résultat à un double - il imprime 0.0
. Où vais-je tort?
Incidemment, l'étape suivante consiste à multiplier ce résultat par 100, ce qui, je suppose, devrait être facile une fois ce petit obstacle franchi.
BTW pas de devoirs ici tout simplement vieux numskull-ness (et peut-être trop codage aujourd'hui).
7 answers
La conversion de la sortie est trop tardive; le calcul a déjà eu lieu en arithmétique entière. Vous devez convertir les entrées en double
:
System.out.println((double)completed/(double)total);
Notez que vous n'avez pas réellement besoin de convertir deux d'entre eux; tant qu'on est double
, l'autre va être implicitement converti. Mais je préfère faire les deux, pour la symétrie.
Vous n'avez même pas besoin de doubles pour cela. Multipliez simplement par 100 d'abord puis divisez. Sinon le résultat serait inférieur à 1 et obtenir tronqué à zéro, comme vous l'avez vu.
Edit: ou si le débordement est probable, s'il déborderait (c'est-à-dire que le dividende est supérieur à 922337203685477581), divisez d'abord le diviseur par 100.
Convertir à la fois completed
et total
en double
ou au moins les convertir en double
lors de la conception. C'est-à-dire lancer les variables pour doubler non seulement le résultat.
Avertissement juste, il y a un problème de précision en virgule flottante lorsque vous travaillez avec float
et double
.
Si vous ne convertissez pas explicitement l'une des deux valeurs en float avant de faire la division, une division entière sera utilisée (c'est pourquoi vous obtenez 0). Vous avez juste besoin que l'un des deux opérandes soit une valeur à virgule flottante, de sorte que la division normale soit utilisée (et que l'autre valeur entière soit automatiquement transformée en flottant).
Essayez simplement avec
float completed = 50000.0f;
Et ça ira.
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
Il suffit de taper cast l'un d'eux.
Comme l'explique le JLS, les opérations entières sont assez simples.
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 en utilisant 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).
Sinon, l'opération est effectuée en utilisant une précision de 32 bits, et le 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.
Donc, pour faire court, une opération toujours un int
, à la seule exception qu'il est un long
valeur.
int = int + int
long = int + long
int = short + short
Notez que la priorité de l'opérateur est importante, donc si vous avez
long = int * int + long
Le int * int
entraînerait une int
, il serait de promouvoir un long
lors de l'opération int + long
Comme votre sortie entraîne un double, vous devez convertir la variable terminée ou la variable totale ou les deux en double lors de la division.
Donc, l'implmentation correcte sera:
System.out.println((double)completed/total);