Why Doesn't Left Bit Shift << Shift Beyond 31 for Long Int Datatype

Why doesn't left bit shift shift beyond 31 for long int datatype?

Although your x is of type long int, the 1 is not. 1 is an int, so 1<<63 is indeed undefined.

Try (static_cast<long int>(1) << 63), or 1L << 63 as suggested by Wojtek.

bit shifting with unsigned long type produces wrong results

1 << 63 will be computed in int arithmetic, and your int is probably 32 bit.

Remedy this by promoting the left argument: 1ULL << 63 will do it.

ULL means the expression will be at least 64 bits.

Why do 1ll i does give us correct answer but not long long i ; 1 i?

C++11 (N3690) 5.8 Shift operators [expr.shift] p1:

The operands shall be of integral or unscoped enumeration type and integral promotions are performed.
The type of the result is that of the promoted left operand.

So the type of 1 << i is int, whereas 1LL << i has type long long, which can usually represent a greater range of values.

The shift operators are exceptional here; most other operators follow the usual arithmetic conversions [5 p10], which cause both operands to be converted to the same type, roughly speaking the larger of the two.

Why doesn't left bit-shift, , for 32-bit integers work as expected when used more than 32 times?

This is caused due to a combination of an undefined behaviour in C and the fact that code generated for IA-32 processors has a 5 bit mask applied on the shift count. This means that on IA-32 processors, the range of a shift count is 0-31 only. 1

From The C programming language 2

The result is undefined if the right operand is negative, or greater than or equal to the number of bits in the left expression’s type.

From IA-32 Intel Architecture Software Developer’s Manual 3

The 8086 does not mask the shift count. However, all other IA-32 processors (starting with the Intel 286 processor) do mask the shift count to 5 bits, resulting in a maximum count of 31. This masking is done in all operating modes (including the virtual-8086 mode) to reduce the maximum execution time of the instructions.



1 http://codeyarns.com/2004/12/20/c-shift-operator-mayhem/

2 A7.8 Shift Operators, Appendix A. Reference Manual, The C Programming Language

3 SAL/SAR/SHL/SHR – Shift, Chapter 4. Instruction Set Reference, IA-32 Intel Architecture Software Developer’s Manual

C left shift on 64 bits fail

Because 1 is an int, 32 bits, so (1 << 27)*27 overflows. Use 1ull.

Regarding your comment, if x is a uint64_t, then 1 << x is still an int, but for the multiplication it would be cast to uint64_t, so there'd be no overflow. However, if x >= 31, 1 << x would be undefined behaviour (as the resulting value cannot be represented by a signed 32 bit integer type).

Bitwise operation for unsigned long long int is not applied when it's over 32bits

Your temp variable only has 32 bits as it is an unsigned int. Change its type to unsigned long long to solve your problem.

What happens?

In this line:

plain |= (temp << (5 * i));

The variable temp has unsigned int type which is typically a 32 bit type. The left shift is therefore also a 32 bit shift and whatever is shifted beyond 32 bits is discarded. The code also exhibits undefined behaviour when i is greater than 6 as shifting a value by more bits than its type has is undefined.

There are two ways to solve this. One is to give temp the right type, the other is to use an appropriate cast to make sure that the shift is an unsigned long long shift:

plain |= ((unsigned long long)temp << (5 * i));

Why bitwise operator produce error in calculating the maximum range possible using same number of bits as provided in an integer

In 1 << count the constant 1 is an int not a long long.

Then the shift overflows.

You should use 1ll << count.

How to shift = 32 bits in uint64_t?

How to shift >= 32 bits in uint64_t?

If your compiler supports long long:

boost::uint64_t x = 1LL << 32;

Otherwise:

boost::uint64_t x = boost::uint64_t(1) << 32;

Shouldn't it be fine since the type has 64 bits?

No. Even though x is 64 bits, 1 isn't. 1 is 32 bits. How you use a result has no effect on how that result is generated.



Related Topics



Leave a reply



Submit