Generate pandoc dataclasses
This commit is contained in:
+380
@@ -0,0 +1,380 @@
|
||||
# Целые числа в 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`:
|
||||
|
||||
```java
|
||||
int a = 2_000_000_000; // ок
|
||||
long b = 9_000_000_000L; // без L будет ошибка компиляции
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Объявление переменных и литералы
|
||||
|
||||
```java
|
||||
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`) — значение нельзя изменить после инициализации:
|
||||
|
||||
```java
|
||||
final int MAX_SCORE = 100;
|
||||
// MAX_SCORE = 200; // ошибка компиляции
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Ввод целых чисел (класс `Scanner`)
|
||||
|
||||
Самый простой способ — `java.util.Scanner`.
|
||||
|
||||
```java
|
||||
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. Вывод целых чисел
|
||||
|
||||
```java
|
||||
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 Арифметические
|
||||
|
||||
```java
|
||||
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 Операции присваивания
|
||||
|
||||
```java
|
||||
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 Сравнение
|
||||
|
||||
```java
|
||||
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 Побитовые операции
|
||||
|
||||
```java
|
||||
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 Приведение типов
|
||||
|
||||
**Автоматическое** (расширяющее) — от меньшего к большему:
|
||||
|
||||
```java
|
||||
byte b = 100;
|
||||
int i = b; // ок
|
||||
long l = i; // ок
|
||||
```
|
||||
|
||||
**Явное** (сужающее) — от большего к меньшему, возможна потеря данных:
|
||||
|
||||
```java
|
||||
int big = 300;
|
||||
byte small = (byte) big; // 300 % 256 = 44 (переполнение)
|
||||
```
|
||||
|
||||
**Переполнение** — опасная ситуация: `int` не может выйти за пределы диапазона и «зацикливается»:
|
||||
|
||||
```java
|
||||
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`-значений (например, «значение отсутствует»).
|
||||
|
||||
```java
|
||||
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()`, а не `==`:
|
||||
> ```java
|
||||
> 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` недостаточно (факториалы, криптография, длинная арифметика):
|
||||
|
||||
```java
|
||||
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`, но есть методы и для целых:
|
||||
|
||||
```java
|
||||
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` — генерация случайных чисел
|
||||
|
||||
```java
|
||||
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. Мини-пример: сумма цифр числа
|
||||
|
||||
```java
|
||||
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
|
||||
// Безопасные операции (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`, ...).
|
||||
- Всегда проверяйте возможность **переполнения** и корректность приведения типов.
|
||||
|
||||
Reference in New Issue
Block a user