Целочисленное суммирование блюза, короткое + = короткая проблема

Программа в С#:

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);

Ответ 1

Здесь есть два вопроса. Во-первых, "почему короткий или короткий результат в int?"

Хорошо, предположим, что короткий плюс короткий был коротким и посмотрел, что произойдет:

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

И среднее, конечно, -9845, если этот расчет сделан в шортах. Сумма больше максимально возможного короткого, поэтому она обертывается до отрицательной, а затем вы делите отрицательное число.

В мире, где целочисленные арифметические обертывания вокруг него гораздо разумнее выполнять все вычисления в int, тип, который, вероятно, будет иметь достаточный диапазон для типичных вычислений, чтобы не переполняться.

Второй вопрос:

  • short plus short is int
  • присвоение int короткому является незаконным
  • a + = b то же, что a = a + b
  • поэтому короткий + = короткий должен быть незаконным
  • так почему это законно?

Вопрос имеет неправильную предпосылку; третья строка выше неверна. Спецификация С# заявляет в разделе 7.17.2

В противном случае, если выбранный оператор предопределенный оператор, если возврат тип выбранного оператора явно конвертируемых в тип x, и если y неявно конвертируемо к типу x или оператору является сдвига, то операция оценивается как x = (T) (x op y), где T является типом x, за исключением того, что x является оценивается только один раз.

Компилятор добавляет приглашение от вашего имени. Правильное рассуждение:

  • short plus short is int
  • присвоение int короткому является незаконным
  • s1 + = s2 совпадает с s1 = (short) (s1 + s2)
  • поэтому это должно быть законным.

Если он не вложил в него бросок, тогда было бы невозможно использовать составное назначение для многих типов.

Ответ 2

Хорошо, оператор += говорит, что вы будете увеличивать значение a коротким, а = говорит, что вы перезапишите значение с результатом операции. Операция a + b дает int, не зная, что она может сделать иначе, и вы пытаетесь присвоить этот int короткому.

Ответ 3

Вы должны использовать:

a = (short)(a + b);

Что касается разницы между поведением назначения и присваивания, я полагаю, что это имеет какое-то отношение к этому (из 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).

Однако, это немного расплывчато, так что mabye кто-то с более глубоким пониманием может прокомментировать.

Ответ 4

Это происходит потому, что int является наименьшим подписанным типом, для которого определен +. Все, что меньше, сначала продвигается до int. Оператор += определяется по отношению к +, но со специальным случаем для обработки результатов, которые не соответствуют цели.

Ответ 5

Это потому, что + = реализуется как перегруженная функция (одна из которых короткая, а компилятор выбирает наиболее специфическую перегрузку). Для выражения (a + b) компилятор расширяет результат до int по умолчанию перед назначением.