Как сложить два числа в Java
Сложение двух чисел в Java с int, long, double и BigDecimal, включая ввод данных пользователем.
Сложение двух чисел — это первая арифметическая операция, которую большинство людей пишут на Java, однако «правильный» способ зависит от того, откуда берутся числа и насколько большими они могут быть. В этой главе рассмотрены идиоматические подходы: целочисленная арифметика с литералами int, разбор значений из текста, сложение чисел с плавающей точкой и безопасное сложение без скрытого переполнения.
Сложение двух значений int
Простейший случай — сложение двух переменных int с помощью оператора +, одного из арифметических операторов Java. Результат также является int.
int a = 7;
int b = 5;
int sum = a + b;
System.out.println(sum); // 12Это повседневный случай, который встречается чаще всего. Единственное, за чем нужно следить, — диапазон int: он хранит значения от -2 147 483 648 до 2 147 483 647. При выходе за этот предел значение молча оборачивается вместо выброса исключения — подробнее об этом ниже.
Сложение чисел, разобранных из текста
Когда числа поступают в виде строк — из консольного ввода, файла или HTTP-запроса — перед сложением их необходимо преобразовать. Используйте Integer.parseInt для целых чисел или Double.parseDouble для десятичных.
String first = "42";
String second = "58";
int sum = Integer.parseInt(first) + Integer.parseInt(second);
System.out.println(sum); // 100Распространённая ошибка новичков — применять + непосредственно к строкам: "42" + "58" даёт "4258", потому что + конкатенирует строки, а не складывает числа. Сначала разберите строку, затем складывайте. Если текст не является допустимым числом, parseInt выбросит NumberFormatException, поэтому при ненадёжном вводе стоит проверить данные или обернуть вызов в try/catch.
Сложение десятичных чисел и обработка переполнения
Для десятичных значений складывайте операнды типа double (или float). Имейте в виду, что двоичная арифметика с плавающей точкой не может точно представить каждое десятичное число, поэтому 0.1 + 0.2 равно 0.30000000000000004, а не 0.3. Для работы с деньгами используйте BigDecimal.
Для целых чисел, которые могут выйти за пределы диапазона int, расширьте один операнд до long или используйте Math.addExact, чтобы переполнение выбрасывало исключение, а не возвращало неверный результат. Выбор правильного числового типа с самого начала — наиболее чистый способ защиты; диапазоны каждого типа описаны в разделе типы данных Java.
| Подход | Поведение при переполнении | Когда применять |
|---|---|---|
int + int | Молча оборачивается | Значения заведомо в пределах диапазона int |
(long) a + b | Вычисляется в 64-битном режиме, без оборачивания | Сумма может превысить int, но помещается в long |
Math.addExact(a, b) | Выбрасывает ArithmeticException | Необходимо обнаружить переполнение, а не поглотить его |
BigInteger / BigDecimal | Произвольная точность | Значения могут быть сколь угодно большими или требуют точных десятичных дробей |
int big = Integer.MAX_VALUE;
System.out.println(big + 1); // -2147483648 (wrapped!)
System.out.println((long) big + 1); // 2147483648 (correct)
System.out.println(Math.addExact(big, 1)); // throws ArithmeticExceptionСложение двух чисел, введённых пользователем
В реальной программе операнды нередко поступают с клавиатуры. Scanner считывает каждую строку и преобразует её в число за один шаг с помощью nextInt (или nextDouble для десятичных), поэтому вызывать parseInt вручную не нужно.
import java.util.Scanner;
public class AddInput {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter first number: ");
int a = scanner.nextInt();
System.out.print("Enter second number: ");
int b = scanner.nextInt();
System.out.println("Sum: " + (a + b));
}
}Если пользователь введёт не целое число, nextInt выбросит InputMismatchException. При ненадёжном вводе защититесь от этого с помощью hasNextInt() или try/catch.
Подробный пример
Что следует вынести из результатов выполнения:
int sum: 12демонстрирует обычный оператор+, складывающий два значенияintнапрямую — повседневный случай.parsed sum: 100подтверждает, чтоInteger.parseIntпревращает"42"и"58"в числа перед сложением, а не конкатенирует их в"4258".double sum: 0.30000000000000004— ошибка представления с плавающей точкой для0.1 + 0.2: доказательство того, чтоdoubleнеточен для десятичных дробей, поэтому при необходимости точности следует использоватьBigDecimal.int overflow: -2147483648показывает, чтоInteger.MAX_VALUE + 1молча оборачивается до наиболее отрицательного значенияint, тогда какlong safe: 2147483648даёт правильный ответ за счёт расширения одного операнда доlong.addExact: overflow detectedподтверждает, чтоMath.addExactвыбрасываетArithmeticExceptionпри том же переполнении вместо возврата неверного значения.