Преобразование типов
В задачах часто смешиваются разные типы: целые и дробные числа, символы и строки. Чтобы выражения считались так, как вы ожидаете, нужно понимать, когда язык делает преобразование автоматически, а когда требуется явное приведение.
В Java у каждой переменной есть тип. Когда в выражении встречаются разные типы, Java либо преобразует типы автоматически, либо требует явное преобразование.
Два вида преобразований
Автоматическое – когда значение точно помещается в более «широкий» тип.
Явное (cast) – когда тип становится «уже» и возможна потеря точности.
Автоматическое преобразование
Чаще всего встречается переход «вверх» по размеру: int → long → double и char → int.
int a = 10;
long b = a; // int → long
double c = b; // long → double
System.out.println(b);
System.out.println(c);
Программа выведет:
Таблица: тип и значение выражения
| выражение | тип выражения | значение выражения |
|---|---|---|
(1 + 2 + 3 + 4) / 4.0 |
double |
2.5 |
Math.sqrt(4) |
double |
2.0 |
"1234" + 99 |
String |
"123499" |
11 * 0.25 |
double |
2.75 |
(int) 11 * 0.25 |
double |
2.75 |
11 * (int) 0.25 |
int |
0 |
(int) (11 * 0.25) |
int |
2 |
(int) 2.71828 |
int |
2 |
Math.round(2.71828) |
long |
3 |
(int) Math.round(2.71828) |
int |
3 |
Integer.parseInt("1234") |
int |
1234 |
7 / 2 |
int |
3 |
(double) 7 / 2 |
double |
3.5 |
'A' + 1 |
int |
66 |
(char) ('A' + 1) |
char |
'B' |
1_000_000_000 * 3 |
int |
-1294967296 |
1_000_000_000L * 3 |
long |
3000000000 |
Ключевые правила
- Если в выражении участвует
double, почти все целочисленные операнды автоматически поднимаются доdouble, и результат тоже становитсяdouble. - Деление
int / intдаётint– дробная часть отбрасывается. - Приведение типа
(int)относится к ближайшему выражению справа. Поэтому скобки критичны:11 * (int) 0.25и(int) (11 * 0.25)– разные вычисления. - При приведении
double → intдробная часть отбрасывается (округления нет). Math.round(double)возвращаетlong(аMath.round(float)–int).- Переполнение
intпроисходит молча. Если нужен точный результат, переводите вlongДО операции:(long) a * bили используйте суффиксLу литерала. - Если слева в
+стоитString, происходит конкатенация строк, а не сложение чисел.
Явное преобразование (cast)
Если тип становится «уже», нужно указать это явно: (int), (long), (double).
При преобразовании double в int дробная часть просто отбрасывается.
Программа выведет:
Деление: int и double
Если делятся два int, результат тоже int – дробная часть отбрасывается.
Программа выведет:
Чтобы получить дробный результат, хотя бы одно число должно быть double.
Программа выведет:
Преобразования в выражениях
В выражении Java поднимает типы до общего и считает в этом типе.
int a = 1;
double b = 2.5;
double s = a + b; // a автоматически превращается в double
System.out.println(s);
Программа выведет:
char как число (код символа)
char можно использовать как число: у символа есть числовой код (Unicode). В выражениях char обычно превращается в int.
char c = 'A';
int code = c; // char → int
char next = (char) (c + 1); // int → char
System.out.println(code);
System.out.println(next);
Программа выведет:
Когда int мало и нужен long
У int ограниченный диапазон: \(-2^{31}\) … \(2^{31}-1\).
У long диапазон больше: \(-2^{63}\) … \(2^{63}-1\).
Если числа точно маленькие – используйте int. Во всех остальных случаях безопаснее long.
Важно помнить про умножение: если оба множителя int, умножение считается в int и может переполниться.
int a = 50_000;
int b = 50_000;
int pInt = a * b;
long pLong = (long) a * b; // переводим в long ДО умножения
System.out.println(pInt);
System.out.println(pLong);
Программа выведет:
String → число и число → String
Если число пришло строкой, его можно преобразовать методами parseInt, parseLong, parseDouble.
Программа выведет:
Число в строку:
Программа выведет:
printf и типы
printf форматирует вывод. Для double часто используют формат %.2f (2 знака после запятой). Перенос строки удобно делать через %n.
Программа выведет:
В C++ преобразования тоже бывают автоматические и явные. В арифметике часто происходит «поднятие» типов: если есть double, вычисления идут в double. Явное приведение пишется как (int) или static_cast<int>(...).
Примеры
int a = 7;
int b = 2;
cout << (a / b) << "\n"; // 3
cout << (double)a / b << "\n"; // 3.5
cout << (int)(11 * 0.25) << "\n"; // 2
Ключевые моменты
int / intдаётint.- Чтобы получить дробный результат, делайте хотя бы один операнд
double. - Приведение вида
(int)относится к ближайшему выражению справа, скобки меняют смысл.
Когда нужен long long
В C++ тип int может переполняться. Для больших значений используют long long. Важно «перевести» в long long ДО операции (например, через суффикс LL).
int a = 1000000000;
cout << a * 3 << "\n"; // переполнение
cout << 1000000000LL * 3 << "\n"; // 3000000000
char и код символа
char в выражениях обычно становится числом (кодом). Чтобы получить следующий символ, можно прибавить 1.
Строка и число
to_string(x)– число в строку.stoi(s)/stoll(s)– строка вint/long long.
В Python тип у значения есть всегда, но переменная может хранить значения разных типов. Преобразования делаются явными функциями int(...), float(...), str(...).
Деление
В Python / всегда даёт дробный результат (тип float), а // – целочисленное деление.
Программа выведет:
int и большие числа
В Python int может быть очень большим, переполнение как у int в Java или C++ обычно не возникает.
Преобразования типов
Программа выведет:
Символ и код
ord(c) – код символа, chr(code) – символ по коду.
Программа выведет:
В Java и C++ типы в арифметике важны всегда: int / int даёт int. В Python оператор / сразу даёт дробный результат, а для целочисленного деления есть отдельный //.
В Java для больших целых чисел обычно используют long. В C++ – long long. В Python int умеет расти и обычно не переполняется.
В Java и C++ автоматическое преобразование чаще идёт «вверх» по типам (например, к double). В Python многие преобразования делают явно через int(...), float(...), str(...).
Переполнение: в Java и C++ переполнение целых типов может произойти без предупреждения, поэтому важно переходить на более широкий тип ДО операции. В Python это обычно не проблема для int.
Символы: в Java char – отдельный тип, и его легко использовать как число (код). В C++ char тоже ведёт себя как маленькое число. В Python «символ» – это строка длины 1, а для кода используют ord и chr.