C'est une question fondamentale mais je ne trouve pas de réponse. J'ai étudié l'arithmétique en virgule flottante et quelques autres sujets, mais rien n'a semblé y remédier. Je suis sûr que j'ai juste la mauvaise terminologie.
En gros, je veux prendre deux quantités - complétées et totales - et les diviser pour obtenir un pourcentage (du montant achevé). 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éattribuer le résultat à un double - il affiche 0.0
. Où vais-je mal?
Incidemment, la prochaine étape consiste à multiplier ce résultat par 100, ce qui, je suppose, devrait être facile une fois ce petit obstacle franchi.
BTW pas les devoirs ici tout simplement plaine vieux numskull-ness (et peut-être trop de codage aujourd'hui).
La conversion de sortie est trop tardive; le calcul a déjà eu lieu en arithmétique entière. Vous devez convertir le entrées en double
:
System.out.println((double)completed/(double)total);
Notez que vous n'avez pas réellement besoin de convertir les deux des entrées. Tant que l'un d'eux est double
, l'autre sera converti implicitement. Mais je préfère faire les deux, par symétrie.
Vous n'avez même pas besoin de doubler pour cela. Il suffit de multiplier par 100 premier et ensuite diviser. Sinon, le résultat serait inférieur à 1 et tronqué à zéro, comme vous l'avez vu.
modifier: ou si un débordement est probable, s’il déborderait (c’est-à-dire que le dividende est supérieur à 922337203685477581), divisez le diviseur par 100 d’abord.
Convertissez completed
et total
en double
ou au moins, convertissez-les en double
lors de la dévision. C'est à dire. Lancez les variantes pour ne pas doubler le résultat.
Attention, il y a un problème de précision en virgule flottante quand on travaille avec float
et double
.
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 le casting l'un ou l'autre.
Si vous ne convertissez pas explicitement l'une des deux valeurs en float avant de procéder à la division, une division entière sera utilisée (c'est pourquoi vous obtenez 0). Il suffit que l'un des deux opérandes soit une valeur à virgule flottante pour que la division normale soit utilisée (et toute autre valeur entière est automatiquement transformée en un flottant).
Juste essayer avec
float completed = 50000.0f;
et ça ira.
Comme expliqué par le JLS , les opérations sur les entiers 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, 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).
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 du type int. Si l'un des opérandes n'est pas un int, il est d'abord élargi au type int par une promotion numérique.
Donc, pour faire court, une opération entraînerait toujours un int
à la seule exception qu'il y ait une valeur long
.
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
opération entraînerait un int
, il serait promu dans un long
au cours de l'opération int + long