uintmax_t не обрабатывает 128 бит

Я хотел определить гигабайт в своем коде, поэтому я использовал, во-первых, unsigned long, Тем не мение, unsigned long не мог справиться 2 * gigabyte,

Итак, я заменил его на long long но я получил ту же ошибку компиляции / предупреждение:
ошибка: целочисленное переполнение в выражении [-Werror = переполнение]

Наконец, я посмотрел на большие целые числа и обнаружил, что мне нужно uintmax_t, так как он 128 бит.

К сожалению, я все еще получаю ту же ошибку. Я предполагаю, что есть небольшая ошибка, но я мог найти это.

Пожалуйста, найдите ниже соответствующий код:

#define kilobyte 1024
#define megabyte 1024 * kilobyte
#define gigabyte 1024 * megabyte
uintmax_t threshold = 2 * gigabyte;

Наконец, после запуска ‘make’

g++ -Wall -Wextra -Werror -pedantic -pthread -std=c++0x -g  -o lcr main.cpp

Я получил:

main.cpp: In function ‘int main(int, char**)’:
main.cpp:104:17: error: integer overflow in expression [-Werror=overflow]
cc1plus: all warnings being treated as errors

3

Решение

Давайте посмотрим на кусок кода:

uintmax_t x = 2 * 1024;

Что здесь происходит, у нас есть (int) 2 * (int) 1024, а затем мы продвигаем результат uintmax_t,

Вместо этого мы хотим: (uintmax_t) 2 * (uintmax_t) 1024, Мы можем легко продвигать целые числа в long long с помощью этого метода:

#define kilobyte 1024ULL
#define megabyte 1024ULL * kilobyte
#define gigabyte 1024ULL * megabyte
uintmax_t threshold = 2ULL * gigabyte;
3

Другие решения

Произведение двух intс явно еще типа int — и литералы, с которыми мы имеем дело в ваших макросах, имеют тип int,
10243 = 230 почти представимо в 32-битной int, Тем не мение, 2 * 230 = 231 точно один слишком большой для 32-разрядного подписанного int держать.

Это может быть решено путем определения констант как объектов соответствующего типа:

const std::uintmax_t kilobyte = 1024;
const std::uintmax_t megabyte = 1024 * kilobyte;
const std::uintmax_t gigabyte = 1024 * megabyte;
const std::uintmax_t threshold = 2 * gigabyte;

Благодаря обычным арифметическим преобразованиям, выполняемым над операндами *переполнение не может произойти.

4

По вопросам рекламы [email protected]