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 fonctionner en lançant:
double d = ((double) num) / denom;
Mais existe-t-il un autre moyen d'obtenir le double
résultat correct ? Je n'aime pas lancer des primitives, qui sait ce qui peut arriver.
java
casting
integer-division
walnutmon
la source
la source
Réponses:
Cela évite un casting. Mais vous constaterez que les conversions de cast sont bien définies. Vous n'avez pas à deviner, vérifiez simplement le JLS . int à double est une conversion élargie. Du §5.1.2 :
5 peut être exprimé exactement comme un double.
la source
1.0
change toujours le type du résultat, juste d'une manière différente. «Cela me semble sale» n'explique pas dans quel (s) scénario (s) vous pensez que la multiplication1.0
est en fait meilleure (ni pourquoi cela pourrait être).(double)num
change en quelque sortenum
. Ce n'est pas le cas - cela crée un double temporaire pour le contexte de l'instruction.Qu'y a-t-il de mal à lancer des primitives?
Si vous ne voulez pas lancer de casting pour une raison quelconque, vous pouvez le faire
la source
double d = num * 1D / denom;
Pourquoi avez-vous une peur irrationnelle de lancer des primitifs? Rien de mauvais ne se produira lorsque vous lancerez un
int
vers undouble
. Si vous n'êtes tout simplement pas sûr de son fonctionnement, recherchez-le dans la spécification du langage Java . La conversion d' unint
versdouble
est une conversion primitive élargie .Vous pouvez vous débarrasser de la paire de parenthèses supplémentaire en transtypant le dénominateur au lieu du numérateur:
la source
double d = (double) num / denom;
... (OK, celui-ci dépend de la priorité)Si vous changez le type de l'une des variables, vous devez vous rappeler d'introduire à nouveau un double si votre formule change, car si cette variable cesse de faire partie du calcul, le résultat est foiré. Je prends l'habitude de lancer le calcul et d'ajouter un commentaire à côté.
Notez que lancer le résultat ne le fera pas
la source
Cast un des entiers / les deux de l'entier à flotter pour forcer l'opération à effectuer avec Math à virgule flottante. Sinon, les mathématiques entières sont toujours préférées. Alors:
Notez que la diffusion du résultat ne le fera pas. Parce que la première division se fait selon la règle de priorité.
Je ne pense pas qu'il y ait de problème avec le casting en tant que tel auquel vous pensez.
la source
Le casting de type est le seul moyen
Produire une
double
division entière - il n'y a pas d'autre moyen sans lancer (peut-être que vous ne le ferez pas explicitement mais cela se produira).Maintenant, il existe plusieurs façons d'essayer d'obtenir une
double
valeur précise (oùnum
etdenom
sont leint
type, et bien sûr avec le casting ) -avec un casting explicite:
double d = (double) num / denom;
double d = ((double) num) / denom;
double d = num / (double) denom;
double d = (double) num / (double) denom;
mais non
double d = (double) (num / denom);
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 pas
double d = 0.0 + ( num / denom );
la source
utilisez quelque chose comme:
(1d est un casting à doubler)
la source
Vous pourriez envisager de boucler les opérations. Par exemple:
Cela vous permet de rechercher (une seule fois) si le casting fait exactement ce que vous voulez. Cette méthode pourrait également être soumise à des tests, afin de s'assurer qu'elle continue à faire ce que vous voulez. Peu importe la astuce que vous utilisez pour provoquer la division (vous pouvez utiliser n'importe laquelle des réponses ici), tant qu'elle aboutit au résultat correct. Partout où vous avez besoin de diviser deux entiers, vous pouvez maintenant simplement appeler
Utils::divide
et avoir confiance qu'il fait la bonne chose.la source
il suffit de l'utiliser.
la source
La meilleure façon de le faire est
la source