db.student.find({}, {"roll":1, "_id":0})
Это эквивалентно -
Выбрать рулон из ученика
blockquote>db.student.find ({}, {"roll": 1, «name»: 1, «_id»: 0})
Это эквивалентно -
Выбрать рулон, имя от ученика
blockquote >
Хотя ваш x
имеет тип long int
, 1
нет. 1
является int
, поэтому 1<<63
действительно не определено.
Попробуйте (static_cast<long int>(1) << 63)
или 1L << 63
, как предложено Wojtek.
Тип данных по умолчанию для числового значения в C является целым числом, если явно не указано.
Здесь вы должны ввести cast 1 как long int, который в противном случае был бы int.
Ваш заголовок вводит в заблуждение; a long
может сдвигаться дальше 31
бит, если long
действительно является большим. Однако ваш код сдвигает 1
, который является int
.
В C ++ тип выражения определяется самим выражением. Выражение XXXXX
имеет тот же тип независимо; если вы позже перейдете double foo = XXXXX;
, это не значит, что XXXXX
является двойным - это означает, что преобразование происходит из того, что XXXXX
было, double
.
Если вы хотите сдвинуть влево длинный, то делайте это явно, например 1L << 32
или ((long)1) << 32
. Обратите внимание, что размер long
варьируется между платформами, поэтому, если вы не хотите, чтобы ваш код прерывался при запуске в другой системе, вам придется принимать дополнительные меры, например, использовать типы фиксированной ширины или перемещаться по CHAR_BIT * sizeof(long) - 1
.
Существует еще одна проблема с вашим предполагаемым кодом: 1L << 63
вызывает неопределенное поведение, если long
имеет значение 64 бит или меньше. Это связано с целым переполнением со знаком; левый сдвиг определяется так же, как повторное умножение на два, поэтому попытка «сдвигаться в бит знака» вызывает переполнение.
Чтобы исправить это, используйте неподписанные типы, где это нормально, чтобы перейти в MSB , например 1ul << 63
.
Технически есть еще одна проблема в том, что ~0
не делает то, что вы хотите, если вы не используете систему дополнений 2, но в наши дни довольно безопасно игнорировать этот случай.
Глядя на ваше намерение с помощью long x = ~0 & ~(1 << 63)
. Более короткий способ написать это:
long x = LONG_MAX;
, который определен <climits>
. Если вам нужна 64-разрядная версия на всех платформах, то
int64_t x = INT64_MAX;
NB. Если вы не собираетесь работать с отрицательными значениями, используйте unsigned long x
и uint64_t
соответственно.
Вы не можете использовать 1 (int по умолчанию), чтобы переместить его за пределы int.
Существует более простой способ получить «все биты, кроме включенного MSB», для определенного типа данных
#include <iostream>
#include <limits>
using namespace std;
int main(){
unsigned long int max = std::numeric_limits<unsigned long int>::max();
unsigned long int max_without_MSB = max >> 1;
cout<< max_without_MSB <<endl;
return 0;
}
Обратите внимание на неподписанный тип. Без numeric_limits
:
#include <iostream>
using namespace std;
int main() {
long int max = -1;
unsigned long int max_without_MSB = ((unsigned long int)max) >> 1;
cout << max_without_MSB << endl;
return 0;
}
Сначала позвольте мне высказать несколько вещей о смене, который является источником вашей проблемы:
Нет гарантии, что long int
на самом деле 64-битный.
Самый общий способ, которым я могу думать, - использовать std::numeric_limits
:
static_cast<long int>(1) << (std::numeric_limits<long int>::digits - 1);
Теперь вы можете даже сделать эту шаблонную функцию constexpr:
template <typename Integer>
constexpr Integer foo()
{
return static_cast<Integer>(1) << (std::numeric_limits<Integer>::digits - 1);
}
Таким образом, заменяя сдвиг с static_cast<long int>(1) << (std::numeric_limits<long int>::digits - 1)
исправит вашу проблему, однако есть намного лучший способ:
std::numeric_limits
включает в себя кучу полезных вещей, в том числе:
std::numeric_limits<T>::max(); // the maximum value T can hold
std::numeric_limits<T>::min(); // the minimum value T can hold
std::numeric_limits<T>::digits; // the number of binary digits
std::numeric_limits<T>::is_signed(); // well, do I have to explain? ;-)
См. cppreference.com для полного списка. Вы должны предпочесть возможности, предоставляемые стандартной библиотекой, потому что у нее, скорее всего, будет меньше ошибок, и другие разработчики сразу это узнают.