68 votes

Blues de sommation entiers, court + = problème court

Programme en C #:

 short a, b;
a = 10;
b = 10;
a = a + b; // Error : Cannot implicitly convert type 'int' to 'short'.

// we can also write this code by using Arithmetic Assignment Operator as given below

a += b; // But this is running successfully, why?

Console.Write(a);
 

71voto

Eric Lippert Points 300275

Il y a deux questions ici. La première est: "pourquoi est court, plus court entraîner int?"

Eh bien, supposons que court, plus court a été de courte et de voir ce qui se passe:

short[] prices = { 10000, 15000, 11000 };
short average = (prices[0] + prices[1] + prices[2]) / 3;

Et la moyenne est, bien sûr, -9845 si ce calcul est effectué en short. La somme est plus grande que la plus grande possible, en bref, il s'enroule autour de négatif, et puis vous divisez le nombre négatif.

Dans un monde où l'arithmétique entière s'enroule autour de il est beaucoup plus judicieux de faire tous les calculs en int, un type qui est susceptible d'avoir assez de gamme typique de calculs, pas de débordement.

La deuxième question est:

  • court, plus court est de type int
  • l'attribution int court est illégal
  • a +=b est le même que a = a + b
  • donc à court += court devrait être illégal
  • alors, pourquoi est-ce légal?

La question a une prémisse inexacte; la troisième ligne ci-dessus est faux. La spécification C# états dans la section 7.17.2

Sinon, si l'opérateur est un prédéfinies de l'opérateur, en cas de retour type de l'opérateur sélectionné est explicitement convertie dans le type de x, et si y est implicitement convertible pour le type de x ou de l'opérateur est un opérateur de décalage, puis l'opération est évalué comme x = (T)(x op y), où T est le type de x, sauf que x est évaluées qu'une seule fois.

Le compilateur insère la fonte sur votre nom. Le bon raisonnement est:

  • court, plus court est de type int
  • l'attribution int court est illégal
  • + s1= s2 est le même que s1 = (short)(s1 + s2)
  • donc ce devrait être légal

Si elle n'a pas insérer de la fonte pour vous, alors il serait impossible d'utiliser des raccourcis sur de nombreux types.

12voto

David Hedlund Points 66192

Eh bien, l'opérateur += indique que vous augmenterez la valeur de a par un court-circuit, tandis que = indique que vous écraserez la valeur, avec le résultat d'une opération. L'opération a + b donne un int, ne sachant pas qu'elle peut faire autrement, et vous essayez de l'attribuer à un court-circuit.

9voto

UpTheCreek Points 7719

Vous devez utiliser:

 a = (short)(a + b);
 

En ce qui concerne la différence entre les comportements d’assignation et d’affectation d’addition, j’imagine que cela a quelque chose à voir avec cela (de msdn)

 x+=y
is equivalent to
x = x + y
except that x is only evaluated once. The meaning of the + operator is
dependent on the types of x and y (addition for numeric operands, 
concatenation for string operands, and so forth).
 

Cependant, c'est un peu vague, donc quelqu'un qui a une compréhension plus profonde peut commenter.

7voto

Marcelo Cantos Points 91211

Cela se produit car int est le plus petit type signé pour lequel + est défini. Tout ce qui est plus petit est d'abord promu en int. L'opérateur += est défini par rapport à + , mais avec une règle de cas particulier pour le traitement des résultats qui ne correspondent pas à la cible.

1voto

Stefan Mai Points 9477

Cela est dû au fait que + = est implémenté en tant que fonction surchargée (l’une d’entre elles est courte et le compilateur choisit la surcharge la plus spécifique). Pour l'expression (a + b), le compilateur élargit le résultat à un int par défaut avant l'affectation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X