Ответ 1
Это примеры операции Сужение примитивного преобразования.
В первом примере long
- int
:
Сужение преобразования знакового целого в интегральный тип T просто отбрасывает все, кроме n бит младшего разряда, где n - количество бит, используемых для представления типа T. В дополнение к возможной потере информации о величине числовое значение, это может привести к тому, что знак результирующего значения будет отличаться от знака входного значения.
Итак, ваш (int) 2147483648l
принимает 64 бита long
:
00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000000
... и полностью отбрасывая верхние 32 бита:
10000000 00000000 00000000 00000000
... и взятие остальных 32 бит как int
. Поскольку самый левый из них теперь является битом знака (long
и int
хранятся в виде двух дополнений), и поскольку он оказывается установленным в вашем значении 2147483648l
, вы получаете отрицательное число. Поскольку никакие другие биты не установлены, в двух дополнениях это означает, что у вас есть самое низкое отрицательное число int
может представлять: -2147483648.
Пример float
to int
следует за более сложным правилом. Соответствующие части для вашей ценности:
... если число с плавающей запятой не является бесконечностью, значение с плавающей запятой округляется до целочисленного значения V, округляя к нулю с использованием режима округления к нулю (IEEE 754) (§4.2.3).
... [if] значение [слишком] (положительное значение большой величины или положительная бесконечность), [тогда] результатом первого шага является наибольшее представимое значение типа int или long.
(Но см. часть спецификации, указанной выше для деталей.)
Так как 2147483648f
округляется до 2147483648
, а 2147483648
слишком велико, чтобы поместиться в int
, вместо этого используется наибольшее значение для int
(2147483647
).
Итак, в long
до int
, это бит битва; в float
до int
, это более математично.
В комментарии вы спросили:
Знаете ли вы, почему оба
(short) 32768
и(short) 32768f
оцениваются на-32768
? Я был последним для оценки до32767
.
Отличный вопрос, и что там, где находится моя "см. часть спецификации, приведенной выше для деталей" выше.:-) (short) 32768f
действительно, (short)(int)32768f
:
В разделе spec, приведенном выше, в разделе "Сужение преобразования числа с плавающей запятой в интегральный тип T принимает два шага:", говорится:
- На первом шаге число с плавающей запятой преобразуется либо в
long
, если T являетсяlong
, либо вint
, если T являетсяbyte
,short
,char
, илиint
...
а затем на втором шаге второй стадии:
- * Если T
byte
,char
илиshort
, результат преобразования является результатом сужения преобразования в тип T (п. 5.1.3) результата первого шага.
Итак, на первом этапе 32768f
становится 32768
(значение int
), а затем, конечно, (short)32768
показывает бит-chopping, который мы видели в long
= > int
выше, что дает нам a short
значение -32768
.