Link to home
Start Free TrialLog in
Avatar of effiqua
effiqua

asked on

How to (left or right shift) all the bits in a 64-bit unsigned integer

unsigned long int mask1 = 0xFFFFFFFFFFFFFFFFUL;

mask1 = mask1 << 64;

Since we are right shifting beyond the width of the data type, compiler is throwing a warning and the value in mask1 is not changed.

Is there any way to right shift all the bits such that the value becomes 0 in mask1.

Other way we can fix is as below :

mask1 = (bitpos == 64) ?  0 : (mask1 << bitpos);

But is there any way we can write this without a check ?, if the right shift have shifted all the bits for any shift width greater than the width of the data type would have been nice.

Thanks,
effiqua.
Avatar of ozo
ozo
Flag of United States of America image

mask1 = (mask1 <<  (bitpos>>1)) << ((bitpos+1)>>1);
But I don't know if that would be preferable to a ? check.
Avatar of HooKooDooKu
HooKooDooKu

What if you just ignore the warning?

The warning I get is "warning C4293: '<<' : shift count negative or too big, undefined behavior", which sort of masks sense.  What's going to happen will be dependent on the type of CPU the compiler has been written for... yet C++ as a language is processor independent.

But if your code is only getting compiled to run on only one type of machine, you could test to see if the 64 bit shift you get is the one you desire, and then just suppress the warning.

#pragma warning(push)
#pragma warning(disable : 4293)
      mask1 = mask1 << 64;
#pragma warning(pop)
Hi,

I find it's difficult to understand the reason for this question at all. IMO the warning only occurs if the 64 is hardcoded, i.e.:
#define SHIFT 64
const int nConstShift = 64;
int nShift = 64;
unsigned long int mask1 = 0xFFFFFFFFFFFFFFFFUL;
unsigned long int mask2 = mask1 << 64; // C4293
unsigned long int mask3 = mask1 << SHIFT; // C4293
unsigned long int mask4 = mask1 << nConstShift; // C4293
unsigned long int mask5 = mask1 << nConstShift; // OK

Open in new window

I wasn't able to find another way to produce this warning.

So why not simply avoid hardocding one of these? :o)

ZOPPO
// This program for learning 64 bit left shift operator  on unsigned long int
#include <stdio.h>
int main()
{
        int bitpos = 64;
        unsigned long int maskFirst = 0xFFFFFFFFFFFFFFFFUL; // 16 F
        unsigned long int maskSecond = 122448;
        unsigned long int maskThird = 0xFFFFFFFFFFFFFFFUL;  // 15 F
        unsigned long y = 64;
        unsigned long z = 0xFFFFFFFFFFFFFFFFUL << y;
        printf( "Current Valye of bitpos [%d]\n", bitpos);
        // maskFirst = 0xFFFFFFFFFFFFFFFFUL << 64;
        printf( "Before change maskFirst:%lu\n", maskFirst);
        if ( sizeof(unsigned long)*8 == bitpos)
        {
                maskFirst  = 0xFFFFFFFFFFFFFFFFUL << 64; // This program assumes that value of maskFirst is 0xFFFFFFFFFFFFFFFFUL
                printf( "maskFirst  = 0xFFFFFFFFFFFFFFFFUL << 64;\n");
        }
        else
        {
                printf( "maskFirst  = maskFirst << bitpos;\n");
                maskFirst  = maskFirst << bitpos;
        }
        printf( "After change maskFirst:%lu\n", maskFirst);
        printf( "Before change maskSecond:%lu\n", maskSecond);
        if ( sizeof(unsigned long)*8 == bitpos)
        {
                maskSecond  = 0xFFFFFFFFFFFFFFFFUL << 64; // This program assumes that value of maskFirst is 0xFFFFFFFFFFFFFFFFUL
                printf( "maskSecond  = 0xFFFFFFFFFFFFFFFFUL << 64;\n");
        }
        else
        {
                maskSecond  = maskSecond << bitpos;
                printf( "maskSecond  = maskSecond << bitpos;\n");
        }
        bitpos = 63;
        printf( "Changed bitpos to [%d]\n", bitpos);
        printf( "Before change maskThird:%lu\n", maskThird);
        if ( sizeof(unsigned long)*8 == bitpos)
        {
                if ( 0xFFFFFFFFFFFFFFFFUL == maskThird)
                {
                        maskThird  = 0xFFFFFFFFFFFFFFFFUL << 64; // This program assumes that value of maskFirst is 0xFFFFFFFFFFFFFFFFUL
                        printf( "maskThird  = 0xFFFFFFFFFFFFFFFFUL << 64;\n");
                }
                else
                {
                        maskThird = maskThird << bitpos;
                        printf( "sizeof bitpos is [%d] maskThird = maskThird << bitpos;\n", sizeof(unsigned long)*8);
                }
        }
        else
        {
                maskThird = maskThird << bitpos;
                printf( "sizeof bitpos is not [%d] maskThird = maskThird << bitpos;\n", sizeof(unsigned long)*8);
        }
        printf( "After change maskThird:%lu\n", maskThird);
        return 0;
}

Open in new window


Output
Current Valye of bitpos [64]
Before change maskFirst:18446744073709551615
maskFirst  = 0xFFFFFFFFFFFFFFFFUL << 64;
After change maskFirst:0
Before change maskSecond:122448
maskSecond  = 0xFFFFFFFFFFFFFFFFUL << 64;
Changed bitpos to [63]
Before change maskThird:1152921504606846975
sizeof bitpos is not [64] maskThird = maskThird << bitpos;
After change maskThird:9223372036854775808

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of HooKooDooKu
HooKooDooKu

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial