15 KiB
Целые числа в Java: теория и практика
1. Что такое целые числа и зачем они нужны
Целое число — это число без дробной части: ..., −3, −2, −1, 0, 1, 2, 3, ...
В программировании целые числа используются для:
- счёта объектов (количество учеников, итераций цикла);
- индексов массивов и коллекций;
- идентификаторов (номер заказа, ID пользователя);
- работы с денежными суммами в копейках/центах (чтобы избежать ошибок округления);
- битовых операций и работы с памятью.
⚠️ Важно: в Java нельзя хранить в целочисленной переменной дробное значение — компилятор выдаст ошибку или потребует явного приведения.
2. Примитивные целочисленные типы
В Java 4 примитивных целочисленных типа, различающихся диапазоном и объёмом памяти:
| Тип | Размер | Диапазон | Применение |
|---|---|---|---|
byte |
8 бит | от −128 до 127 | экономия памяти в массивах, работа с байтами |
short |
16 бит | от −32 768 до 32 767 | редко, в основном в устаревшем коде |
int |
32 бита | от −2 147 483 648 до 2 147 483 647 | основной тип по умолчанию |
long |
64 бита | от −9.2·10¹⁸ до 9.2·10¹⁸ | большие числа, время в миллисекундах |
Запомните: по умолчанию любое целое литеральное число в Java имеет тип int. Чтобы получить long, добавьте суффикс L:
int a = 2_000_000_000; // ок
long b = 9_000_000_000L; // без L будет ошибка компиляции
3. Объявление переменных и литералы
byte small = 100;
short medium = 30_000;
int normal = 1_000_000;
long big = 123_456_789_012L;
// Системы счисления:
int decimal = 255; // 10-я
int hex = 0xFF; // 16-я (префикс 0x)
int binary = 0b1111_1111; // 2-я (префикс 0b)
int octal = 0377; // 8-я (ведущий 0)
// Подчёркивания для читаемости
int million = 1_000_000;
Константы (final) — значение нельзя изменить после инициализации:
final int MAX_SCORE = 100;
// MAX_SCORE = 200; // ошибка компиляции
4. Ввод целых чисел (класс Scanner)
Самый простой способ — java.util.Scanner.
import java.util.Scanner;
public class InputDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Введите целое число: ");
int n = sc.nextInt(); // читает int
System.out.print("Введите длинное число: ");
long L = sc.nextLong(); // читает long
System.out.print("Введите байт: ");
byte b = sc.nextByte();
System.out.println(String.format("Вы ввели: %d, %d, %d", n, L, b));
sc.close();
}
}
Для чтения из файла/строки можно использовать Scanner(new File("input.txt")) или BufferedReader.
5. Вывод целых чисел
int x = 42;
// Если нужно вывести только число — подходит обычный println:
System.out.println(x); // 42
// Когда нужен текст или форматирование — String.format:
System.out.println(String.format("x = %d", x));
// Форматирование в разных системах счисления:
System.out.println(String.format("hex = %x, bin = %s",
255, Integer.toBinaryString(255)));
// hex = ff, bin = 11111111
// Выравнивание и ширина поля:
System.out.println(String.format("|%5d|", 42)); // | 42|
System.out.println(String.format("|%-5d|", 42)); // |42 |
System.out.println(String.format("|%05d|", 42)); // |00042|
Часто используемые спецификаторы String.format:
| Спецификатор | Смысл |
|---|---|
%d |
целое в 10-й системе |
%x |
16-я система |
%o |
8-я система |
%05d |
целое с ведущими нулями, ширина 5 |
%n |
перевод строки (переносимый) |
6. Основные операции
6.1 Арифметические
int a = 17, b = 5;
System.out.println(a + b); // 22
System.out.println(a - b); // 12
System.out.println(a * b); // 85
System.out.println(a / b); // 3 — ЦЕЛОЧИСЛЕННОЕ деление
System.out.println(a % b); // 2 — остаток от деления
⚠️ Деление целых чисел отбрасывает дробную часть, а не округляет:
7 / 2 == 3,-7 / 2 == -3(округление к нулю).
6.2 Операции присваивания
int x = 10;
x += 5; // x = 15
x -= 3; // x = 12
x *= 2; // x = 24
x /= 4; // x = 6
x %= 4; // x = 2
x++; // x = 3
x--; // x = 2
6.3 Сравнение
int p = 5, q = 7;
boolean r1 = p == q; // false
boolean r2 = p != q; // true
boolean r3 = p < q; // true
boolean r4 = p >= q; // false
6.4 Побитовые операции
int m = 0b1100; // 12
int n = 0b1010; // 10
System.out.println(m & n); // 8
System.out.println(m | n); // 14
System.out.println(m ^ n); // 6
System.out.println(~m); // -13
System.out.println(m << 1); // 24 (сдвиг влево = ×2)
System.out.println(m >> 1); // 6 (сдвиг вправо)
System.out.println(m >>> 1); // 6 (беззнаковый сдвиг)
6.5 Приведение типов
Автоматическое (расширяющее) — от меньшего к большему:
byte b = 100;
int i = b; // ок
long l = i; // ок
Явное (сужающее) — от большего к меньшему, возможна потеря данных:
int big = 300;
byte small = (byte) big; // 300 % 256 = 44 (переполнение)
Переполнение — опасная ситуация: int не может выйти за пределы диапазона и «зацикливается»:
int max = Integer.MAX_VALUE;
System.out.println(max + 1); // -2147483648
7. Критерии применимости целых чисел
Используйте целочисленный тип, если:
- Величина по своей природе дискретна — количество, индекс, счётчик.
- Нужна точность без округлений — деньги (лучше в копейках), ID, временные метки.
- Выполняются операции над целыми — деление нацело, остаток, битовые сдвиги.
- Важна производительность — целочисленная арифметика быстрее вещественной.
- Нужна экономия памяти — например,
byte[]для большого массива.
Не используйте целые числа, если:
- величина непрерывна (расстояние, температура, вес) — берите
double/float; - нужна высокая точность над дробными числами —
BigDecimal.
Выбор типа:
- по умолчанию —
int; - если значения > 2·10⁹ или работа со временем в мс —
long; - для больших массивов малых чисел —
byte/short; - для чисел, не помещающихся ни в один примитив (> 9.2·10¹⁸) —
BigInteger.
8. Классы стандартной библиотеки
8.1 Классы-обёртки: Integer, Long, Short, Byte
Каждому примитиву соответствует класс-обёртка. Нужен для:
- хранения в коллекциях (
ArrayList<Integer>); - использования полезных методов;
null-значений (например, «значение отсутствует»).
Integer obj = 42; // автоупаковка (autoboxing)
int prim = obj; // автораспаковка (unboxing)
// Полезные методы (там, где выводится только число — println):
System.out.println(Integer.MAX_VALUE); // 2147483647
System.out.println(Integer.MIN_VALUE); // -2147483648
System.out.println(Integer.parseInt("123")); // 123
System.out.println(Integer.compare(3, 5)); // -1
System.out.println(Integer.max(3, 5)); // 5
System.out.println(Integer.sum(3, 5)); // 8
System.out.println(Integer.bitCount(7)); // 3
System.out.println(Integer.numberOfLeadingZeros(1)); // 31
// Там, где результат — строка — String.format:
System.out.println(String.format("%s", Integer.toBinaryString(10))); // 1010
System.out.println(String.format("%s", Integer.toHexString(255))); // ff
⚠️ Сравнивайте объекты-обёртки через
.equals(), а не==:Integer a = 1000, b = 1000; System.out.println(a == b); // false (разные объекты) System.out.println(a.equals(b)); // trueКэш
Integerработает только для значений от −128 до 127, поэтомуInteger a = 100; Integer b = 100; a == bдастtrue, но для 1000 — ужеfalse.
8.2 BigInteger — для чисел произвольной длины
Когда long недостаточно (факториалы, криптография, длинная арифметика):
import java.math.BigInteger;
BigInteger a = new BigInteger("123456789012345678901234567890");
BigInteger b = BigInteger.valueOf(987654321L);
System.out.println(a.add(b)); // сложение
System.out.println(a.subtract(b)); // вычитание
System.out.println(a.multiply(b)); // умножение
System.out.println(a.divide(b)); // деление
System.out.println(a.mod(b)); // остаток
System.out.println(a.pow(2)); // возведение в степень
System.out.println(a.gcd(b)); // НОД
// Факториал 100:
BigInteger fact = BigInteger.ONE;
for (int i = 2; i <= 100; i++)
fact = fact.multiply(BigInteger.valueOf(i));
System.out.println(fact);
BigInteger иммутабелен — операции возвращают новый объект, а не меняют исходный.
8.3 Math — математические функции
Работает с double, но есть методы и для целых:
System.out.println(Math.abs(-7)); // 7
System.out.println(Math.max(3, 8)); // 8
System.out.println(Math.min(3, 8)); // 3
// Math.pow / Math.sqrt возвращают double — для форматирования используем String.format:
System.out.println(String.format("%.1f", Math.pow(2, 10))); // 1024.0
System.out.println(String.format("%.1f", Math.sqrt(144))); // 12.0
8.4 Random — генерация случайных чисел
import java.util.Random;
Random rnd = new Random();
int r1 = rnd.nextInt(); // любое int
int r2 = rnd.nextInt(100); // [0, 100)
int r3 = rnd.nextInt(50) + 1; // [1, 50]
System.out.println(r2);
System.out.println(r3);
// Начиная с Java 17 — RandomGenerator:
// int r = java.util.random.RandomGenerator.getDefault().nextInt(1, 101);
9. Мини-пример: сумма цифр числа
import java.util.Scanner;
public class SumDigits {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Введите целое число: ");
long n = Math.abs(sc.nextLong());
int sum = 0;
while (n > 0) {
sum += (int)(n % 10); // последняя цифра
n /= 10; // отбрасываем её
}
System.out.println(sum);
}
}
Здесь задействованы: long, % и /, приведение типов, ввод/вывод, Math.abs.
10. Типичные ошибки
| Ошибка | Как избежать |
|---|---|
| Деление нацело вместо дробного | Привести один операнд: (double) a / b |
Переполнение int |
Использовать long или Math.addExact (бросает исключение) |
Сравнение обёрток через == |
Использовать .equals() |
Забыть L у большого литерала |
long x = 3000000000L; |
NullPointerException при распаковке |
Проверять на null перед присваиванием в примитив |
Потеря точности при (int) longValue |
Проверять диапазон или использовать Math.toIntExact |
// Безопасные операции (Java 8+):
int sum = Math.addExact(1_000_000_000, 1_000_000_000); // ArithmeticException
int prod = Math.multiplyExact(100_000, 100_000); // исключение
11. Итоги
- В Java 4 примитивных целочисленных типа; основной —
int, для больших значений —long. - По умолчанию целые литералы —
int, дляlongнужен суффиксL. - Деление целых отбрасывает дробную часть, остаток даёт
%. - Для чисел > 9.2·10¹⁸ используйте
BigInteger. - Для коллекций и
null— классы-обёртки (Integer,Long, ...). - Всегда проверяйте возможность переполнения и корректность приведения типов.