Приведение результата умножения двух положительных целых чисел на long является отрицательным значением

У меня есть такой код:

int a = 629339;
int b = 4096;
long res = a*b;

Результат-1717194752 но если я добавлю одно ручное приведение к длинномуlong res = ((long)a)*b; или жеlong res = (long) a*b; результат правильный2577772544 Кто может объяснить, как это работает.

Ответы на вопрос(3)

a*b целое число, а не длинное.

Потому что это'Это всего лишь целое число, оно уже ограничено 32-битным пределом.

Приведение этого целого числа к длинному не восстановит эти данные волшебным образом.

Решение Вопроса
long res = a*b;

a*b будет рассматриваться как целое число, если вы не добавите 'l' в конце (или) приведение.

СогласноJava-учебник

Тип данных int - это 32-битный со знаком двадополнить целое число. Он имеет минимальное значение -2 147 483 648 и максимальное значение 2 147 483 647 (включительно). Для целочисленных значений этот тип данных обычно является выбором по умолчанию, если только нет причины (как указано выше) выбрать что-то еще.

 Lemberg12 окт. 2012 г., 17:12
И, как я понимаю, Java не приводит типы автоматически к типу результата?
 kosa12 окт. 2012 г., 17:14
Да, это правильно. Существуют правила определения типа результата. Позвольте мне посмотреть, смогу ли я найти эту документацию для вас.

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

long res = a*b;

Шаг 1 - получить значенияa а также .b

Шаг 2 - оценитьa * b, посколькуa а такжеb обаintс, этоint умножение. Итак, мы умножаем629339 от629339 который был бы2577772544, К несчастью,2577772544 больше, чем максимально возможная Javaint значение ... так что операция умножения молчапереполнение ... и мы получаем-1717194752 вместо.

Шаг 3 Мы назначаем значение RHS для LHS. Поскольку RHS являетсяint и LHSfloatJLS говорит, что мы выполняемпримитивное расширение преобразование ... которое просто поворачивается-1717194752 вlong с тем же значением. Расширенное значение затем присваивается.res

Чтобы получить ожидаемый ответ, мы должны принудительно выполнить умножение, используяlong арифметика. Например:

long res = ((long) a) * b;

В этом случае мы имеем умножениеlong поintи это решается путем расширенияint кlong и выполняяlong умножать. Это больше не переполняется (потому что2577772544 значительно ниже самого большогоlong значение), поэтому, когда мы, наконец, присвоить значениеres, это число, которое вы ожидали.

 Stephen C12 окт. 2012 г., 17:44
В Java расширение до типа результата происходит в конечном назначении и неt влияет на способ оценки выражения RHS.
 Stephen C12 окт. 2012 г., 17:52
Кроме того, мой C ++ ржавый, но я считаю, что C ++ ведет себя так же, как Java в этом отношении.
 Lemberg12 окт. 2012 г., 18:04
Поведение ++ зависит от используемого компилятора.
 Lemberg12 окт. 2012 г., 17:31
Как я знаю в C ++, результат всех арифметических операций приведен к типу результата. Ява не делает это автоматически /
 Stephen C12 окт. 2012 г., 18:19
Вздох ... спасибо, что напомнили мне об одной из причин, по которой яушел из C и C ++

Ваш ответ на вопрос