Неподписанная длинная длинная ошибка переполнения?

У меня были некоторые странные проблемы с unsigned long long.

Это происходит, когда я устанавливаю длинную без знака (я использовал size_t, однако проблема повторяется с u-l-l). Я установил его на 2 ^ 31, однако по какой-то причине он возвращается к 18446744071562067968 или 2 ^ 64 — 2 ^ 31. Имейте в виду, я использую компиляцию x64:

unsigned long long a = 1 << 31;
cout << a;

//Outputs 18446744071562067968, Expected 2147483648

Я думал, что пределы u-l-l были 2 ^ 64-1? Так почему же 2 ^ 31 нельзя хранить? 2 ^ 30 работает просто отлично. Sizeof (a) возвращает 8, что составляет 64 бита, если я не ошибаюсь, доказывая ограничение 2 ^ 64-1.

Я компилирую на Visual C ++ 2013 Express Desktop.

Мое единственное предположение, что это какая-то ошибка переполнения, потому что она не соответствует обычному типу long.

2

Решение

То, что вы видите, это расширение знака, когда отрицательное целое значение присваивается длинному длинному без знака.

Чтобы исправить это, вам нужно сделать значение unsigned для начала примерно таким:

#include <iostream>
#include <iomanip>

int main()
{
unsigned long long a = 1ull << 31ull;
std::cout << a << "\n";
std::cout << std::hex << a << "\n";

return 0;
}

Если уровень предупреждения достаточно высок (/ W4), вы увидите предупреждение о несоответствии со знаком или без знака.

Просто чтобы завершить, вам не нужно квалифицировать оба аргумента, просто левый операнд в порядке, так что unsigned long long a = 1u << 31; должно сработать. Я просто предпочитаю быть максимально явным.

2

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


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