0Pricing
C++ Academy · Урок

Числовые ограничения и переполнение

Запрашивайте std::numeric_limits и изучайте правила переполнения знаковых и беззнаковых типов.

«Числовые ограничения и переполнение» — бесплатный урок C++ Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Почему важны ограничения типов

У каждого числового типа есть максимальное и минимальное представимое значение. Их превышение может незаметно привести к неправильным результатам или неопределённому поведению.

std::numeric_limits

Получить ограничения любого числового типа можно с помощью заголовочного файла <limits>. Это константы времени компиляции, поэтому дополнительных затрат во время выполнения нет.

#include <limits>
std::cout << std::numeric_limits<int>::max() << "\n";
std::cout << std::numeric_limits<int>::min() << "\n";
std::cout << std::numeric_limits<double>::epsilon();

Распространённые запросы

Наиболее полезные члены:

  • max() — наибольшее значение
  • min() — наименьшее положительное значение
  • lowest() — наиболее отрицательное значение
  • epsilon() — наименьшая значимая разница (для чисел с плавающей точкой)
  • digits10 — гарантированное количество десятичных цифр

Переполнение знакового целого числа

Переполнение знакового целого числа — это неопределённое поведение. Компилятор может предполагать, что оно никогда не происходит, и выполнять неожиданные оптимизации.

int x = std::numeric_limits<int>::max();
x += 1;   // UB — anything can happen

Зацикливание беззнакового целого числа

Переполнение беззнакового типа определено: значения зацикливаются по модулю 2^N. Иногда это полезно, но часто становится источником ошибок.

unsigned int u = 0;
u -= 1;   // wraps to 4,294,967,295 (UINT_MAX)

Переполнение и потеря точности чисел с плавающей точкой

При переполнении числа с плавающей точкой превращаются в inf, а не приводят к аварийному завершению. При потере точности результатом становятся субнормальные числа или 0.

double x = 1e308;
x *= 100;
std::cout << x;  // inf

Безопасное обнаружение переполнения

Для знаковых целых чисел проверяйте возможность переполнения до выполнения операции. Компиляторы предоставляют встроенные средства проверяемой арифметики, например __builtin_add_overflow в GCC/Clang.

if (a > std::numeric_limits<int>::max() - b) {
    // overflow would happen
}
int sum = a + b;

C++20: std::ssize и std::cmp_less

В C++20 в <utility> появились безопасные вспомогательные функции для сравнения целых чисел: std::cmp_equal, cmp_less, cmp_greater. Они корректно обрабатывают смешивание знаковых и беззнаковых типов.

Неявные преобразования таят опасность

Смешивание знаковых и беззнаковых типов при сравнении незаметно преобразует знаковый операнд в беззнаковый — это частый источник трудно обнаруживаемых ошибок.

int a = -1;
unsigned int b = 1;
if (a < b) std::cout << "yes";
else       std::cout << "no";   // prints "no"!

Проверки во время компиляции

Используйте static_assert, чтобы проверять предположения о размерах при написании переносимого кода.

static_assert(sizeof(int) >= 4, "Need at least 32-bit int");

Средства санитизации помогают при тестировании

Соберите программу с -fsanitize=undefined, чтобы обнаруживать переполнение знаковых чисел во время выполнения при тестировании.

g++ -fsanitize=undefined -O1 main.cpp

Быстрая проверка

Что происходит при переполнении сложения знакового целого числа в C++?

Итоги

Используйте std::numeric_limits, чтобы получать границы типов. Переполнение знаковых чисел не определено, а беззнаковые значения зацикливаются. Смешивайте знаковые и беззнаковые типы с большой осторожностью. Санитайзеры и безопасные сравнения C++20 помогают защитить код.

Часто задаваемые вопросы

Урок «Числовые ограничения и переполнение» бесплатный?

Да — полный текст урока «Числовые ограничения и переполнение» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Числовые ограничения и переполнение»?

Запрашивайте std::numeric_limits и изучайте правила переполнения знаковых и беззнаковых типов. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Числовые ограничения и переполнение»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Целочисленные типы и типы с плавающей точкой
  2. Заголовок cmath: pow, sqrt, abs, round
  3. Случайные числа с заголовком random
  4. Числовые ограничения и переполнение
← Назад к C++ Academy