Files
tasks-to-mdl/input/T02.md
T
2026-09-14 19:26:07 +03:00

15 KiB
Raw Blame History

Целые числа в 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. Критерии применимости целых чисел

Используйте целочисленный тип, если:

  1. Величина по своей природе дискретна — количество, индекс, счётчик.
  2. Нужна точность без округлений — деньги (лучше в копейках), ID, временные метки.
  3. Выполняются операции над целыми — деление нацело, остаток, битовые сдвиги.
  4. Важна производительность — целочисленная арифметика быстрее вещественной.
  5. Нужна экономия памяти — например, 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, ...).
  • Всегда проверяйте возможность переполнения и корректность приведения типов.