Расчет диапазона примитивов Java

В Java, когда мы объявляем

short number=1024*1024*1024; 

он даст ошибку времени компиляции, но

short number=1024 * 1024 * 1024 * 1024;

компилируется отлично. Почему это происходит?

Ответ 1

В этом случае компилятор оценивает вычисление (потому что он содержит только константы) и пытается присвоить результат переменной. Этот расчет выполняется с типом int и преобразовывается в short при назначении, если это вообще возможно.

В вашем случае первый расчет слишком велик, чтобы вписаться в short (1073741824). Второй переполняет int и заканчивается в диапазоне, поддерживаемом short (0). Таким образом, назначение работает в этом случае.

Помните, вы, вероятно, никогда не хотите полагаться на эти вещи в коде.

Ответ 2

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

Потеря точности означает, что вы теряете информацию о данном значении (короткий тип данных представляет собой 16-битное подписанное целое число из двух дополнений, минимальное значение -32,768 и максимальное значение 32 767 (включительно).) В вашем первом случае диапазон коротких пересекается (1073741824), и, следовательно, вы теряете информацию.

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

EDIT: -

От JLS §3.10.1 (очень правильно указано в этот аналогичный вопрос)

Это ошибка времени компиляции, если десятичный литерал типа int больше чем 2147483648 (2 31), или если появляется десятичный литерал 2147483648 где угодно, кроме как операнд унарного оператора-минуса (§15.15.4).