#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] .. работает