Преобразование типов

В задачах часто смешиваются разные типы: целые и дробные числа, символы и строки. Чтобы выражения считались так, как вы ожидаете, нужно понимать, когда язык делает преобразование автоматически, а когда требуется явное приведение.

В 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);

Программа выведет:

10
10.0

Таблица: тип и значение выражения

выражение тип выражения значение выражения
(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) возвращает longMath.round(float)int).
  • Переполнение int происходит молча. Если нужен точный результат, переводите в long ДО операции: (long) a * b или используйте суффикс L у литерала.
  • Если слева в + стоит String, происходит конкатенация строк, а не сложение чисел.

Явное преобразование (cast)

Если тип становится «уже», нужно указать это явно: (int), (long), (double).

При преобразовании double в int дробная часть просто отбрасывается.

double x = 3.99;
int a = (int) x;

System.out.println(a);

Программа выведет:

3

Деление: int и double

Если делятся два int, результат тоже int – дробная часть отбрасывается.

int a = 7;
int b = 2;

System.out.println(a / b);

Программа выведет:

3

Чтобы получить дробный результат, хотя бы одно число должно быть double.

int a = 7;
int b = 2;

double q = (double) a / b;
System.out.println(q);

Программа выведет:

3.5

Преобразования в выражениях

В выражении Java поднимает типы до общего и считает в этом типе.

int a = 1;
double b = 2.5;

double s = a + b; // a автоматически превращается в double
System.out.println(s);

Программа выведет:

3.5

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);

Программа выведет:

65
B

Когда 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);

Программа выведет:

-1794967296
2500000000

String → число и число → String

Если число пришло строкой, его можно преобразовать методами parseInt, parseLong, parseDouble.

String s = "123";
int x = Integer.parseInt(s);

System.out.println(x + 7);

Программа выведет:

130

Число в строку:

int x = 42;
String s = String.valueOf(x);

System.out.println("x = " + s);

Программа выведет:

x = 42

printf и типы

printf форматирует вывод. Для double часто используют формат %.2f (2 знака после запятой). Перенос строки удобно делать через %n.

int a = 7;
int b = 2;

double q = (double) a / b;
System.out.printf("q = %.2f%n", q);

Программа выведет:

q = 3.50

В 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.

char c = 'A';
cout << (int)c << "\n";        // 65
cout << (char)(c + 1) << "\n"; // B

Строка и число

  • to_string(x) – число в строку.
  • stoi(s) / stoll(s) – строка в int / long long.

В Python тип у значения есть всегда, но переменная может хранить значения разных типов. Преобразования делаются явными функциями int(...), float(...), str(...).

Деление

В Python / всегда даёт дробный результат (тип float), а // – целочисленное деление.

a = 7
b = 2

print(a / b)
print(a // b)

Программа выведет:

3.5
3

int и большие числа

В Python int может быть очень большим, переполнение как у int в Java или C++ обычно не возникает.

x = 10**18
print(x * 3)

Преобразования типов

print(int(3.99))
print(float(7))
print(str(123) + "99")

Программа выведет:

3
7.0
12399

Символ и код

ord(c) – код символа, chr(code) – символ по коду.

c = 'A'
print(ord(c))
print(chr(ord(c) + 1))

Программа выведет:

65
B

В 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.