Целочисленное суммирование блюз, короткая + = короткая задача - PullRequest
68 голосов
/ 03 декабря 2010

Программа на 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);

Ответы [ 5 ]

71 голосов
/ 03 декабря 2010

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

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

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

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

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

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

  • шорт плюс шорт - это инт
  • присваивание int короткому недопустимо
  • a + = b совпадает с a = a + b
  • поэтому short + = short должно быть недопустимым
  • так почему это законно?

У вопроса неверная предпосылка; третья строка выше неверна. Спецификация C # говорится в разделе 7.17.2

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

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

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

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

12 голосов
/ 03 декабря 2010

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

9 голосов
/ 03 декабря 2010

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

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

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

7 голосов
/ 03 декабря 2010

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

1 голос
/ 03 декабря 2010

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

...