Ошибка CPP: переполнение целых чисел в выражении

#c #long-long

#c #типы

Вопрос:

Я пытаюсь представить 16 ГБ в байтах и uint64_t выдает ошибку.

Какой тип данных я должен использовать для его представления? unsigned long int также выдает ошибку.

 error: integer overflow in expression [-Werror=overflow]
         uint64_t TESTBYTES = 16 * 1024 * 1024 * 1024;
  

Ответ №1:

uint64_t TESTBYTES = 16ULL * 1024 * 1024 * 1024 сделает это.

В противном случае выражение 16 * 1024 * 1024 * 1024 вычисляется как an int с неопределенными результатами на вашей платформе, поскольку вы переполняете int тип.

ULL переводит первый термин в an unsigned long long , вызывая продвижение других терминов. Это всегда безопасно, поскольку an unsigned long long должно быть не менее 64 бит.

Комментарии:

1. С каким типом данных?

2. что такое ULL? Другой вопрос: если в какой-то момент я определяю другую вызываемую переменную uint64_t TEST1BYTES и добавляю к ней 64 байта .. например, TEST1BYTES =64; Он выдаст ошибку, как только достигнет предела. Кстати, спасибо

3. A uint64_t должно быть равно нулю, если вы превысите наибольшее значение, чтобы ошибка не выдавалась. Но вам не мешало бы переполнить 64-битный беззнаковый путем последовательного добавления 64; потребуется несколько лет даже с шагом в наносекунду.

4. Это правда. Просто спрашиваю — это может произойти.

Ответ №2:

Как есть, ваше выражение состоит из целых литералов без суффиксов и будет оцениваться как целое число со знаком, а значение переполнится. Результатом вашего выражения является 17179869184 и максимальное значение, которое может содержать 32-разрядное целое 2147483647 число, поэтому оно переполнится. Чтобы принудительно вычислить выражение как значение без знака (в вашем случае без знака long long), вы должны добавить суффикс ULL or ull к одному из ваших операндов (кроме последнего, как указано в комментариях), чтобы все выражение вычислялось как unsigned long long . Тривиальный пример, демонстрирующий, что происходит:

 #include <iostream>
#include <cstdint>
#include <limits>

int main() {
    uint64_t x; // unsigned long long
    auto y = 16 * 1024 * 1024 * 1024; // evaluated as int, the result overflows
    auto z = 16ull * 1024 * 1024 * 1024; // evaluated as unsigned long long, does not overflow
    std::cout << "Your expression: " << z << 'n';
    std::cout << "Maximum integer value: " << std::numeric_limits<int>::max() << 'n';
    std::cout << "Maximum unsigned long long value: " << std::numeric_limits<unsigned long long>::max() << 'n';
    x = z;
}
  

Комментарии:

1. Не какой-либо один аргумент: добавление его, скажем, к последнему делает код уязвимым на платформах с 16 битами int .

2. в обоих случаях это все равно приведет к сбою.. uint64_t CapacityBytes[] = {16ULL * 1024 * 1024 * 1024, 16ULL * 1024 * 1024 * 1024};

3. Спасибо за комментарий. Не могли бы вы также ответить на приведенный выше вопрос?

4. Переполнение происходит в выражении умножения, а не вычитания типа переменной. Неверно говорить «результат не подходит» для y строки

5. @M.M: Я думаю, что как массив проблема заключается error: too many initializers for ‘uint64_t [0] не в том, что у нас есть выражения умножения.. потому что unint64_t[2] .. работает