Влияние назначения типов параметров на переполнение целых чисел

#java #integer-overflow

#java #целое число-переполнение

Вопрос:

Мне трудно понять поведение java в следующем сценарии. Например, у меня есть метод multiply, который просто умножает два значения int и выводит результат на экран.

 private static void multiply() {

    int firstValue = Integer.MAX_VALUE;
    int secondValue = 2;                   //double secondValue=2 

    double result = firstValue * secondValue;

    System.out.println("Result is: "   result);
}
  

и из-за того, что переполнение целых чисел, результат равен -2. Однако здесь результат вычисления присваивается двойному, который принимает гораздо большее значение, чем умножение FirstValue и secondValue.

Мои вопросы к этой проблеме;

1- Почему происходит переполнение целых чисел, хотя результат присваивается двойному?

2- Когда я меняю тип secondValue на double (упоминается в комментарии), результат верен. Почему Java ведет себя по-разному, когда тип одного из множителей изменяется на double?

Комментарии:

1. Вычисление производится как целое число, и результат преобразуется в double только после вычисления. Итак, есть момент, когда ваш int в два раза больше MAX_VALUE, что даст ваш результат

2. Умножение включает только целые числа, поэтому оно выполняется как целочисленное умножение. Только после этого результат преобразуется в double, но в это время уже слишком поздно. Приведите одно из значений при умножении.

Ответ №1:

Java не поддерживается target type casting .

 private static void multiply() {

    int firstValue = Integer.MAX_VALUE;
    int secondValue = 2;
    double one = 1.0;
    double result = one * firstValue * secondValue;

    System.out.println("Result is: "   result);
}
  

Target Type casting означает приведение значения результата к типу переменной, которой оно должно быть присвоено.
Таким образом, он не знает, что результат должен быть присвоен double переменной. В этом случае int это самый большой тип данных, поэтому выражение вычисляется в int типе данных.
если вы умножаете его на double единицу, выражение вычисляется в double type и ответ правильный.

Комментарии:

1. Однако в вашем примере, когда переменная one находится в конце (двойной результат = FirstValue * secondValue * one), переполнение целых чисел все равно происходит. Я думаю, java смотрит порядок переменной в вычислении или?

2. Это из-за порядка операций.

Ответ №2:

Результатом умножения двух int s является значение an int , которое может переполняться или не переполняться, в зависимости от значения умножения. Как только этот результат получен, он только затем повышается до a double , после того, как могло произойти переполнение.

Если один из операндов является a double , результатом умножения будет a double , что допускает гораздо больший диапазон, чем an int .

Комментарии:

1. Однако, если вы посмотрите на пример Ankit. Когда я помещаю переменную one , которая равна double, в конце вычисления, переполнение целых чисел все равно происходит, даже если один из множителей равен double.

2. @AdInfinitum Это потому, что порядок операций. Два целых числа сначала умножаются на переполнение, затем умножаются на удвоение и повышаются.

3. @AndrewL. Спасибо. Вы правы. После вашего комментария я помещаю последние два множителя (secondValue и one ) в круглые скобки, и это дает правильный ответ.

Ответ №3:

это ожидаемо, потому что, когда вы умножаете 2 целых числа, результатом является только целое число. Это работает с другим способом, когда вы используете double в качестве одного из полей, результат будет рассматриваться как двойное значение. тип данных получателей здесь не имеет значения