public class Solution {
public static void main(String[] args) {
int a = 0; //а=0
int b = (byte) a + 46; //b=46
byte c = (byte) (a * b); //c=0*46=0
double f = (char) 1234.15; //f=1234
long d = (short) (a + f / c + b);
}
}
почему JVM не ругается на деление на 0 в f/c?LeMeldonium
22 уровень
почему JVM не ругается на деление на 0?
Решен
Комментарии (7)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Ksenia VolkovaJava Developer в DXCMaster
16 января 2020, 05:38решение
Если бы там был int, то ругалась бы.
Но для double все немного иначе, там есть NaN - not a number
+3
LeMeldonium
16 января 2020, 08:12
Спасибо, кажется разобрался.
Получается что NaN для лонга это его максимальное значение - 9223372036854775807
И если мы это представляем как short то программа пытается уместить, перебирая диапазон до тех пор пока максимальное значение не закончится. И так совпало, что значение заканчивается на -1. Верно?
0
Ksenia VolkovaJava Developer в DXCMaster
16 января 2020, 08:50
Прошу прощения, NaN - это 0 разделить на 0.
А любое положительное число при делении на 0 даст + бесконечность (POSITIVE_INFINITY)
POSITIVE_INFINITY обозначается последовательностью байт 0x7ff0000000000000, что для лонга соответствует значению 9223372036854775807.
При преобразовании его в любой другой целочисленный тип получится -1.
+3
LeMeldonium
16 января 2020, 09:09
А это вызвало ещё вопросов.
почему тогда так получается? В первом случае выдало максимальное значение int. Мы же в первых двух случаях подавали максимальное значение для long.
Не понятно. Вроде, бы и short, и int меньше чем long, но для одного -1, а для другого максимальное число.
0
Ksenia VolkovaJava Developer в DXCMaster
16 января 2020, 10:13
Там надо разбираться, как в каждом случае происходит преобразование байтовой последовательности
+1
Белич МаксимРаботает в BelEnergo ❤
30 июня 2021, 06:02
Уже несколько дней пытаюсь разобраться в этом вопросе. Стало понятней, но не все. На stackoverflow не получил ответа, спрошу у вас тут.
Хотел бы получить объяснение про преобразование бесконечности к целочисленным типам. Например:
Я создаю переменную d типа double и присваиваю ей значение положительной бесконечности. Далее, я преобразовываю эту бесконечность к типу int и на выходе получаю значение 2147483647.
Вопрос 1: почему дробная положительная бесконечность преобразовалась в максимальное возможное значение для int?
Далее, среда разработки показывает, что POSITIVE_INFINITY это некое число в шестнадцатеричной системе счисления (0x7ff0000000000000L). На выходе мы получаем, что это число в int будет равно 0. Используя обычный калькулятор перевода чисел из одной системы в другую получим число (0x7ff0000000000000L) в двоичной системе - 111111111110000000000000000000000000000000000000000000000000000.
Вопрос 2. Последние 32 бита равны 0, старшие биты откидываются и поэтому int равен 0? Вопрос 3. Почему Double.POSITIVE_INFINITY(0x7ff0000000000000L) имеет на конце литерал L? Это же не лонг? Вопрос 4. Почему, когда в 4 строчке кода я вывожу:
Результатом получается снова максимальное число для int? Как происходит в данном случае сужение типа?
0
Ksenia VolkovaJava Developer в DXCMaster
30 июня 2021, 14:38
POSITIVE_INFINITY в двоичном представлении выглядит как последовательность 111111111110000000000000000000000000000000000000000000000000000.
Число 9218868437227405312 в двоичном представлении выглядит точно так же.
(в HEX это будет 0x7ff0000000000000L - и это именно long, в int это число не влезет, тут 8 байт).
Но это не значит, что POSITIVE_INFINITY и 9218868437227405312 - это одно и то же число.
У double своя структура, часть байт в double выделены под мантиссу, часть - под экспоненту.
(double)0x7ff0000000000000L и Double.longBitsToDouble(0x7ff0000000000000L) - это два разных числа (второе - POSITIVE_INFINITY, первое - нет).
Про порядок приведения double к целочисленным типам можно почитать в документации.
+2