Win a copy of The Way of the Web Tester: A Beginner's Guide to Automating Tests this week in the Testing forum!

# Storing constants by shifting bits

Arunan Ramanathan
Greenhorn
Posts: 24
Hi,
I worked in a project, the code was written 5yrs back by experienced java developers. They have created an interface
to store constant values, there they store the constant values in the following format

int CONSTANT_1 = 1<<5;
int CONSTANT_2 = 1<<8;

int CONSTANT_3 = 0X01;
int CONSTANT_4 = 0X01<<2;

Why did they stored the constant values like this.Why they are doing bit shifting operations and storing

Karthik Shiraly
Bartender
Posts: 1210
25
One reason I can think of is that these are being used as bit masks.
Do a bitwise AND of a number with CONSTANT_1, for example, and it will tell whether the 5th bit in that number is set or not.
This technique was common to store multiple states of something in 1 byte, to save memory in the old days.
Still quite common in low memory environments.
See where these constants are used to get a clue what was being ANDed.
Certainly, very bad naming practices to call it 'CONSTANT_1' and the like.

David Newton
Author
Rancher
Posts: 12617
No idea. When I define bit flags like this I just use the hex value; it's easier to read and understand. I was more likely to see code like that in embedded systems C code from 20 years ago.

Note also that the "constant interface" anti-pattern is somewhat suspect:

http://en.wikipedia.org/wiki/Constant_interface

Rob Spoor
Sheriff
Posts: 20709
68
Using the shift operator tells you immediately that CONSTANT_1 is an int with all bits but the 6th one set to 0. Sure, you could have just written 32, but that isn't as clear as "only bit 5" which is what 1 << 5 essentially means.

HEX is often used because it too is more natural when used in bitwise computations. The decimal system we all know is really not intuitive when applied to bitwise computations. Binary would be the most intuitive but since there is no support typing those octal or hexadecimal are the best remaining options. Octal is often not used because it may confuse starting programmers who do not recognize the leading 0. I've answered a question about this just last week or so, where someone encountered the (octal) number 0100 and thought it was 100, instead of 64.

Campbell Ritchie
Sheriff
Posts: 50749
83
When Rob said "6th" bit and "only bit 5" it sounds confusing. Remember bits are usually 0-based reading from right to left, rather like array indices. A field identifier like CONSTANT_1 to mean "bit 5 set" is also confusing.

Arunan Ramanathan
Greenhorn
Posts: 24
Karthic,
If i copy and paste the real constant name then i may got fired from the company ;-)

Rob,
Instead of assigning the constant value 32 they are doing bit shift operations, they assigned the
value as 1 << 5. In my perspective this code leads to poor maintainance and less understandable code.
How your explanation "only bit 5" fits into the following operation,

Binary representation of 1 = 1
After shifting 5 bits to the left the val will be = 100000

Please give me an explanation, i m dying to find the answer. Because this code is written by a 10yr
experienced java programmer, i think there might be a proper reason for assigning a constant
value like this.

HEX is often used because it too is more natural when used in bitwise computations
Usually hex and octal is used in system level programming.I used bit operations once in my
life time , when i write a c code to find the processor family and processor model. So i am not
able to feel the naturality :-)

May be the answer for me lies in your previous reply, may be i am not able to interpret your

David Newton
Author
Rancher
Posts: 12617
He's saying that some people would find it more intuitive to read "1 << 6" as "there's a one, six bits over".

I don't, but I used to program directly in octal and hex, so these kinds of things don't bother me.

Don't assume because someone has been doing something for a long time that there's *always* a reason, or that it's a good one. In this case either way is fine, and neither the shift nor the hex is difficult to read.

Rob Spoor
Sheriff
Posts: 20709
68
How your explanation "only bit 5" fits into the following operation,

Binary representation of 1 = 1
After shifting 5 bits to the left the val will be = 100000

Let's explain with byte, since that has fewer bits (32 for int, 8 for byte) so I can save on bits The same principle holds for both though, and also short and long.
Any byte can be represented as 8 bits. For instance:
As you can see, 1 << 5 means that only bit number 5 is set to 1. Maybe the term "only bit 5" was poorly chosen, it's a number with all bits set to 0 except bit 5 which is set to 1.

Where you probably would have preferred 32, and David probably prefers 0x20 or 040, I find 1 << 5 just a little bit easier to read.
Compare decimal vs hexadecimal vs binary:
If I need a number that with only one bit set to 1 and the others set to 0, I prefer the shifted way. But in the end, it's all a matter of preference. No matter if you use 32, 0x20, 040 or 1 << 5, the compiler will turn it into 32.

Arunan Ramanathan
Greenhorn
Posts: 24
Rob,
Wonderful explanation
Thanks a lot

Carey Brown
Bartender
Posts: 1755
22
I've used both the HEX and BIT SHIFT approaches over the years. One advantage of the BIT SHIFT is that it is easy to reorder your values if you should need to insert a new constant in between two existing constants thereby needing to shift the values below it an additional bit.

Before
A = 1 << 0;
B = 1 << 1;
C = 1 << 2;

After
A = 1 << 0;
X = 1 << 1;
B = 1 << 2;
C = 1 << 3;

David Newton
Author
Rancher
Posts: 12617
I don't see how that's substantially easier.

Rob Spoor
Sheriff
Posts: 20709
68
You only need to renumber one digit (or two if you get past 1024), instead of renumbering all full numbers. Still, this wouldn't be a reason for me to do this. First of all, X should be added at the end. By changing the values of B and C you need to recompile all classes that use them, since the compiler substitutes compile time constants with their values. Second, you need to change all values either way. A bit of cut-and-pasting wouldn't take that much more effort.