Почему отличное деление на нулевые целые примитивы дает разные результаты?

    System.out.println((byte) (1.0/0));
    System.out.println((short) (1.0/0));
    System.out.println((int) (1.0/0));
    System.out.println((long) (1.0/0));

Результат:

    -1
    -1
    2147483647
    9223372036854775807

В двоичном формате:

    1111 1111
    1111 1111 1111 1111
    0111 1111 1111 1111 1111 1111 1111 1111
    0111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111

Почему отлитие бесконечности до int и длинных целых чисел сохраняет знак бит как "0", а устанавливает бит знака в "1" для байтов и коротких целых чисел?

Ответ 1

JLS 5.1.3:

Сужение преобразования числа с плавающей запятой интегральному типу T выполняется двумя шагами:

На первом этапе число с плавающей запятой преобразуется либо в long, если T длинный или int, если T байт, короткий, char или int, следующим образом:

Если число с плавающей запятой NaN (п. 4.2.3), результат первого шаг преобразования - это int или long 0.

В противном случае, если число с плавающей запятой не является бесконечностью, значение с плавающей запятой округляется до целочисленного значения V, округляя к ноль с использованием режима IEEE 754 round-to-zero (§4.2.3). Тогда есть два случая:

Если T длинно, и это целочисленное значение может быть представлено как длинное, то результатом первого шага является длинное значение V.

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

В противном случае должен выполняться один из следующих двух случаев:

Значение должно быть слишком маленьким (отрицательное значение большой величины или отрицательная бесконечность), а результат первого шага - наименьший представляемое значение типа int или long.

Значение должно быть слишком большим (положительное значение большой величины или положительная бесконечность), а результатом первого шага является наибольшая представляемое значение типа int или long.

На втором шаге:

Если T int или long, результат преобразования является результатом первый шаг.

Если T байт, char или короткий, результатом преобразования является результат сужения преобразования типа T (п. 5.1.3) результата первый шаг.

Итак, бесконечное двойное значение сначала добавляется к int, возвращая Integer.MAX_VALUE, а затем оно добавляется к byte/short, которое принимает соответствующее количество низких байтов (и получает -1 как результат). Отбрасывания до int и long не имеют этого дополнительного шага, но byte и short идут сначала через int, а затем в byte/short.