web-dev-qa-db-fra.com

Division entière: Comment faites-vous un double?

Pour ce bloc de code:

int num = 5;
int denom = 7;
double d = num / denom;

la valeur de d est 0.0. Il peut être forcé de travailler en utilisant:

double d = ((double) num) / denom;

Mais existe-t-il un autre moyen d'obtenir le résultat double correct? Je n'aime pas les primitifs, qui sait ce qui peut arriver.

226
walnutmon
double num = 5;

Cela évite un casting. Mais vous constaterez que les conversions de casting sont bien définies. Vous n'avez pas à deviner, vérifiez simplement JLS . int to double est une conversion en expansion. De §5.1.2 :

L'élargissement des conversions primitives ne perd pas d'informations sur la magnitude globale d'une valeur numérique.

[...]

La conversion d'une valeur int ou longue en float, ou d'une valeur longue en double, peut entraîner une perte de précision. En d'autres termes, le résultat peut perdre certains des bits les moins significatifs de la valeur. Dans ce cas, la valeur en virgule flottante résultante sera une version correctement arrondie de la valeur entière, utilisant le mode arrondi au plus proche IEEE 754 (§4.2.4) .

5 peut être exprimé exactement comme un double.

146
Matthew Flaschen

Quel est le problème avec les primitives de casting?

Si vous ne voulez pas lancer pour une raison quelconque, vous pouvez le faire

double d = num * 1.0 / denom;
94
Paul Tomblin

Je n'aime pas les primitifs, qui sait ce qui peut arriver.

Pourquoi avez-vous une peur irrationnelle de lancer des primitifs? Il ne se passera rien de mal lorsque vous convertissez un int en un double. Si vous n'êtes pas sûr de son fonctionnement, recherchez-le dans le Spécification du langage Java . La conversion de int en double est une conversion de primitive d'élargissement .

Vous pouvez vous débarrasser de la paire de parenthèses supplémentaire en définissant le dénominateur à la place du numérateur:

double d = num / (double) denom;
67
Jesper

Si vous modifiez le type de l'une des variables, vous devez vous rappeler d'insérer à nouveau un double si votre formule change, car si cette variable cesse de faire partie du calcul, le résultat est erroné. Je prends l'habitude de jouer un rôle dans le calcul et d'ajouter un commentaire à côté de celui-ci.

double d = 5 / (double) 20; //cast to double, to do floating point calculations

Notez que le résultat ne fera pas le résultat

double d = (double)(5 / 20); //produces 0.0
25
alianos-

Convertissez l'un des entiers/les deux entiers en float pour forcer l'opération à être effectuée avec Math en virgule flottante. Sinon, Math est toujours préférable. Alors:

1. double d = (double)5 / 20;
2. double v = (double)5 / (double) 20;
3. double v = 5 / (double) 20;

Notez que le résultat ne le fera pas. Parce que la première division est faite selon la règle de priorité.

double d = (double)(5 / 20); //produces 0.0

Je ne pense pas qu'il y ait un problème avec le casting en tant que tel auquel vous songez.

15
Nikhil Kumar

Le casting de type est le seul moyen


Produire un double à partir d'une division entière - il n'y a pas d'autre moyen sans casting (peut-être que vous ne le ferez pas explicitement, mais cela arrivera).

Maintenant, il y a plusieurs façons d'obtenir une valeur double précise (où num et denom sont int type, et bien sûr avec casting ) -

  1. avec casting explicite:

    • double d = (double) num / denom;
    • double d = ((double) num) / denom;
    • double d = num / (double) denom;
    • double d = (double) num / (double) denom;

mais pas double d = (double) (num / denom);

  1. avec casting implicite:

    • double d = num * 1.0 / denom;
    • double d = num / 1d / denom;
    • double d = ( num + 0.0 ) / denom;
    • double d = num; d /= denom;

mais pas double d = num / denom * 1.0;
et non double d = 0.0 + ( num / denom );

8
Minhas Kamal

utiliser quelque chose comme:

double step = 1d / 5;

(1d est un casting pour doubler)

2
ungalcrys

Vous pourriez envisager de boucler les opérations. Par exemple:

class Utils
{
    public static double divide(int num, int denom) {
        return ((double) num) / denom;
    }
}

Cela vous permet de regarder (une seule fois) si le casting fait exactement ce que vous voulez. Cette méthode peut également être soumise à des tests, pour vous assurer qu'elle continue de faire ce que vous voulez. Le truc que vous utilisez pour provoquer la division importe peu (vous pouvez utiliser n'importe laquelle des réponses ici), dans la mesure où le résultat est correct. Partout où vous avez besoin de diviser deux entiers, vous pouvez désormais appeler Utils::divide et vous assurer que le résultat est correct.

0

juste utiliser ceci.

int fxd=1;
double percent= (double)(fxd*40)/100;
0
Mabood Ahmad

La meilleure façon de faire est

int i = 3;
Double d = i * 1.0;

d is 3.0 now.
0
Alp Altunel