web-dev-qa-db-fra.com

Division des entiers dans Java

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 longs. 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).

84
Ben

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.

123
Oliver Charlesworth

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.

8
harold

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.

3
Ali
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.

2
Bhavya Jain

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.

1
Jack

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

0
AxelH