bit shift and data type of a constant value

F

Felix Kater

Hi,

when I use something like

int Shift= 3;
long Value= 1 << Shift;

What is the data type of the const value '1' here? In other terms: What
is the possible maximum of 'Shift' here?

If I want to make sure to make the shift operation work on at least
32 bit (given a 32 bit system) does it help to cast or is it senseless:

long Value=((unsigned int)1) << Shift;

Felix
 
J

jacob navia

Felix Kater a écrit :
1)
What is the data type of the const value '1' here?

This is an integer constant since it is not suffixed with L, or LL. Type
is 'int'.

2)
What
What is the possible maximum of 'Shift' here?

It is sizeof(int)*CHAR_BIT - 1

3)
> If I want to make sure to make the shift operation work on at least
> 32 bit (given a 32 bit system) does it help to cast or is it senseless:
>
> long Value=((unsigned int)1) << Shift;

The cast is useless since '1' is ALREADY an int. But since you are
assigning to a long it would be more logical to write:

long Value = 1L << Shift;

In this case 1L is a long integer, and in 32 bit systems it will
be probably 32 bits, and in some 64 bit systems it will be 64 bits.

In this case,

long Value= 1L << Shift;

Shift <= sizeof(long)*CHAR_BIT - 1

In most systems, long long is 64 bits, so if you want a fairly portable
construct with maximum range use:

long long Value = 1LL << Shift;

then you will have Shift <= sizeof(long long)*CHAR_BIT - 1, in most
systems 63.

jacob
 
F

Flash Gordon

jacob navia wrote, On 04/04/07 08:34:

Jacob, what has happened to your quoting? Thunderbird normally inserts
the quote markers correctly, so I suspect you have accidentally changed
something. I've fixed the quoting.
Felix Kater a écrit :

This is an integer constant since it is not suffixed with L, or LL. Type
is 'int'.


It is sizeof(int)*CHAR_BIT - 1

No, for signed types you need -2 to avoid overflow. For unsigned types
-1 is OK.
The cast is useless since '1' is ALREADY an int.

Incorrect, since the case converts it to *unsigned* int and thus allows
it to be shifted a bit further without any risk.
> But since you are
assigning to a long it would be more logical to write:

long Value = 1L << Shift;
Yes.

In this case 1L is a long integer, and in 32 bit systems it will
be probably 32 bits, and in some 64 bit systems it will be 64 bits.

In this case,

long Value= 1L << Shift;

Shift <= sizeof(long)*CHAR_BIT - 1

In most systems, long long is 64 bits, so if you want a fairly portable
construct with maximum range use:

long long Value = 1LL << Shift;

then you will have Shift <= sizeof(long long)*CHAR_BIT - 1, in most
systems 63.

Not quite, if you want maximum range use an unsigned type, then there is
no risk of overflow.

In general it is best to use unsigned types for bit twiddling.
 
P

pete

jacob said:
Felix Kater a écrit :
1)
What is the data type of the const value '1' here?

This is an integer constant since it is not suffixed with L, or LL. Type
is 'int'.

2)
What
What is the possible maximum of 'Shift' here?

It is sizeof(int)*CHAR_BIT - 1

That's too high.

Concerning (E1 << E2):
N869
6.5.7 Bitwise shift operators
[#4] The result of E1 << E2 is E1 left-shifted E2 bit
positions; vacated bits are filled with zeros. If E1 has an
unsigned type, the value of the result is E1×2E2, reduced
modulo one more than the maximum value representable in the
result type. If E1 has a signed type and nonnegative value,
and E1×2E2 is representable in the result type, then that is
the resulting value; otherwise, the behavior is undefined.
3)

The cast is useless since '1' is ALREADY an int. But since you are
assigning to a long it would be more logical to write:

The cast to unsigned, prevents undefined behavior,
though (unsigned long) would be a better choice for the above.
Bit operations involving the sign bit,
are either implementation defined or undefined.
long Value = 1L << Shift;

In this case 1L is a long integer, and in 32 bit systems it will
be probably 32 bits, and in some 64 bit systems it will be 64 bits.

In this case,

long Value= 1L << Shift;

Shift <= sizeof(long)*CHAR_BIT - 1

In most systems, long long is 64 bits,
so if you want a fairly portable
construct with maximum range use:

long long Value = 1LL << Shift;

then you will have Shift <= sizeof(long long)*CHAR_BIT - 1, in most
systems 63.

long long Value = = 1LL << sizeof(long long)*CHAR_BIT - 1;

is undefined.
 
S

santosh

Felix said:
Hi,

when I use something like

int Shift= 3;
long Value= 1 << Shift;

What is the data type of the const value '1' here?

Because you've used no type suffixes it's an int value.
In other terms: What
is the possible maximum of 'Shift' here?

That'd be sizeof(1)*CHAR_BIT - 2.
If I want to make sure to make the shift operation work on at least
32 bit (given a 32 bit system) does it help to cast or is it senseless:

long Value=((unsigned int)1) << Shift;

int is only guaranteed to be atleast 16 bits. long is guaranteed to be
atleast 32 bits. So the cast above should be to long or unsigned long,
depending on the type of Value.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,247
Latest member
crypto tax software1

Latest Threads

Top