web-dev-qa-db-fra.com

Entier sommant les bleus, 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);

Il y a deux questions ici. Le premier est "pourquoi le résultat court plus court dans int?"

Eh bien, supposons que court plus court était court et voyez 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 de -9845 si ce calcul se fait en short. La somme est plus grande que le plus grand court possible, elle est donc négative, puis vous divisez le nombre négatif.

Dans un monde où l'arithmétique entière s'enroule, il est beaucoup plus judicieux de faire tous les calculs en entier, un type qui a probablement une plage suffisante pour que les calculs typiques ne débordent pas.

La deuxième question est:

  • court plus court est int
  • attribuer int à short est illégal
  • a + = b est identique à a = a + b
  • donc court + = court devrait être illégal
  • alors pourquoi est-ce légal?

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

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

Le compilateur insère la distribution en votre nom. Le raisonnement correct est le suivant:

  • court plus court est int
  • attribuer int à short est illégal
  • s1 + = s2 est le même que s1 = (court) (s1 + s2)
  • donc cela devrait être légal

S'il n'insérait pas la distribution pour vous, il serait impossible d'utiliser l'affectation composée sur de nombreux types.

71
Eric Lippert

Eh bien, le += L'opérateur dit que vous augmenterez la valeur de a avec un court, tandis que = indique que vous écrasez la valeur, avec le résultat d'une opération. L'opération a + b donne un entier, ne sachant pas qu'il peut faire autrement, et vous essayez d'affecter cet entier à un court.

12
David Hedlund

Vous devez utiliser:

a = (short)(a + b);

Quant à la différence entre les comportements d'affectation 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.

9
UpTheCreek

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 int. Le += L'opérateur est défini par rapport à +, mais avec une règle de cas spécial pour gérer les résultats qui ne correspondent pas à la cible.

7
Marcelo Cantos

En effet, + = est implémenté en tant que fonction surchargée (dont l'une 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 de l'attribuer.

1
Stefan Mai