У меня были некоторые странные проблемы с 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.
То, что вы видите, это расширение знака, когда отрицательное целое значение присваивается длинному длинному без знака.
Чтобы исправить это, вам нужно сделать значение 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;
должно сработать. Я просто предпочитаю быть максимально явным.