Как посчитать количество значений в типе int
Что проверяют
Базу: размер int, дополнительный код и поведение при переполнении. Настоящий тест в том, заметите ли вы ловушку, когда начнёте считать это в коде. Следом часто спрашивают, чему равны Integer.MAX_VALUE + 1 и Math.abs(Integer.MIN_VALUE).
Как отвечать
int в Java всегда 32-битный знаковый, независимо от платформы, это закреплено спецификацией языка. Значит, значений 2 в степени 32, то есть 4 294 967 296. Диапазон от -2147483648 (Integer.MIN_VALUE) до 2147483647 (Integer.MAX_VALUE). Отрицательных на одно больше, чем положительных: ноль забирает одно место из неотрицательной половины.
Если просят показать в коде, переходите в long до вычитания:
long count = (long) Integer.MAX_VALUE - Integer.MIN_VALUE + 1;Или короче: 1L << Integer.SIZE. Константы Integer.SIZE (32) и Integer.BYTES (4) лучше хардкода.
Что стоит добавить:
- переполнение молчаливое:
Integer.MAX_VALUE + 1даётInteger.MIN_VALUEбез исключения. Если нужна проверка, естьMath.addExact, он броситArithmeticException; Math.abs(Integer.MIN_VALUE): возвращает отрицательное число, у минимума нет положительной пары;- беззнаковые операции: с Java 8 есть
Integer.toUnsignedLong,Integer.divideUnsigned,Integer.compareUnsigned, чтобы трактовать те же 32 бита как числа от 0 до 2 в степени 32 без единицы; - другие типы:
byte8 бит,short16,long64,char16 бит без знака.
Где спотыкаются
Пишут (long) (max - min + 1). Выражение в скобках считается в int, переполняется и даёт 0, а приведение к long применяется уже к нулю.
Проверяют такое через assert и радуются чистому запуску. Проверки assert по умолчанию выключены, без флага -ea JVM их пропускает, и ошибка выше остаётся незамеченной.
Путают Java с C и C++, где размер int зависит от платформы и компилятора. В Java он фиксирован, поэтому ответ «зависит от машины» здесь неверен.