mreff555
mreff555

Reputation: 1121

Is there a limit of n bits when bit shifting?

While trying to come up with a scheme for a bitboard class, I decided use global compile time variables to represent key bit board configurations, ex. the initial position of all black rooks.

constexpr uint64_t BLACK_ROOK_INIT  = 0x1 | (0x1 << 56);

However I am getting compiler errors. The compiler appears to be treating this value as a 32 bit value and type casting or adding additional 0's does not seem to make a difference. The type definition is from .

As soon as I drop constexp from this expression it compiles, however still produces the equivalent warning. Why is this happening? I thought it might be a limitation of the pre-processor, but the problem persists without constexp.

chess.cpp:16:64: error: right operand of shift expression ‘(1 << 56)’ is >= than the precision of the left operand [-fpermissive]

FYI, this also does not compile

constexpr int64_t BLACK_ROOK_INIT = (int64_t)0x1 | (int64_t)(0x1 << 32);

Upvotes: 1

Views: 2188

Answers (2)

Harsh Vardhan
Harsh Vardhan

Reputation: 1

here 1 is int and after shifting it crosses the limit of int. so firstly we need to convert int to long long int(a/c to your requirements)

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin>>n;                
    ll l=(long long int)1<<n;
    cout<<l<<endl;
}  

Upvotes: 0

Richard
Richard

Reputation: 61369

This is what you want:

#include <iostream>

int main(){
  constexpr uint64_t BLACK_ROOK_INIT  = 0x1ULL | (0x1ULL << 56);
  std::cout<<BLACK_ROOK_INIT<<std::endl;
}

Your 0x1 value is, by default, an int, which is usually implemented as a 32-bit integer.

The suffixes are discussed here. If they make you a bit uncomfortable, as they do me, you can cast as follows:

#include <iostream>

int main(){
  constexpr uint64_t BLACK_ROOK_INIT  = (uint64_t)(0x1) | ((uint64_t)(0x1) << 56);
  std::cout<<BLACK_ROOK_INIT<<std::endl;
}

Upvotes: 2

Related Questions