2010-03-31 16 views
11

J'ai codé quelques trucs de calcul (j'ai copié ci-dessous un exemple vraiment simplifié de ce que j'ai fait) comme CASE2 et j'ai obtenu de mauvais résultats. Refactorisé le code comme CASE1 et a bien fonctionné. Je sais qu'il y a une distribution implicite dans CASE 2, mais pas sûr de la raison complète. Tout le monde pourrait m'expliquer ce qui se passe exactement ci-dessous?Explication de casting/conversion int/double en C#

//CASE 1, result 5.5 
    double auxMedia = (5 + 6); 
    auxMedia = auxMedia/2; 

    //CASE 2, result 5.0 
    double auxMedia1 = (5 + 6)/2; 

    //CASE 3, result 5.5 
    double auxMedia3 = (5.0 + 6.0)/2.0; 

    //CASE 4, result 5.5 
    double auxMedia4 = (5 + 6)/2.0; 

Je pense que/2 dans CASE2 est coulée (5 + 6) int et provoquant cycle de division à 5, puis coulé à nouveau pour doubler et converti en 5,0. CASE3 et CASE 4 résout également le problème.

+2

En note; il y a seulement * une * opération effectuée à l'exécution ici. Le '/ 2' dans le cas 1. Le reste est tout fait par le compilateur. –

+0

@Marc: le compilateur ne peut-il pas exécuter le cas 1 entièrement au moment de la compilation, puisque 'auxMedia' est local et affecté d'une constante? Ou s'agit-il d'une optimisation laissée strictement au JIT? –

+0

@Michael - J'attendrais * que cela soit laissé au JIT. Pour y répondre, vous devez regarder différentes sorties du compilateur ... –

Répondre

13
  1. 5 + 6 est un nombre entier de 11; que vous avez ensuite moulé pour doubler (dans le devoir) et diviser par deux; 5,5
  2. 5 + 6 est un nombre entier de 11; nombre entier 11/2 = sous arithmétique de nombres entiers, ce qui vous puis coulée à double (dans l'affectation)
  3. 5,0 + 6,0 est le double de 11,0; diviser par le double 2,0 donnant le double 5,5
  4. 5 + 6 est un entier de 11; il y a une distribution implicite pour doubler 11,0 pour la division, puis diviser deux doubles donnant 2,0 5,5
+0

Marc a raison. Si votre deuxième ligne était 'auxMedia = auxMedia/2.0' alors vous obtiendrez le résultat attendu puisque' 2.0' est lu comme un double et '2' est lu comme un int (il supprime tous les chiffres décimaux - ne même rond). – Jaxidian

1
//CASE 2, result 5.0 
double auxMedia1 = (5 + 6)/2; 

Le résultat de l'opération (5 + 6) est entier. Parce que les deux opérandes sont de type entier. Ensuite, le compilateur effectue 11/2, où les deux opérandes sont également des entiers. Le résultat de la dernière division est évidemment 5, parce que c'est une division entière (ne sait pas le mot anglais approprié).

1

Vous avez raison. CAS 2 utilise l'arithmétique entière jusqu'à ce que l'affectation soit faite. Vous pouvez également résoudre le problème en faisant un explicite casting:

double auxMedia1 = ((double) (5 + 6))/2; 
5

développiez de (correct) Marc répondre à un peu, les nombres entiers sont interprétés comme entier, alors que le nombre avec décimales sont interprétées comme double. Pour déclarer un nombre entier comme un double littéral, ajoutez un "D" à celui-ci:

 //CASE 2b, result 5.5 
     double auxMedia2b = (5D + 6D)/2;