
I have interviewed countless IT professionals and am stunned that bits and bytes are foreign words to most of them. I have been with IT for a long time; since we had nothing but assemblers. In today's world, where the costs to buy 16 GB RAM is $50, going to that level may be irrelevant for application servers... but in the world of protocols and IoT, it is very important.
Primitives
Numerical values can be signed or unsigned. Signed means they have minus values, unsigned means they don't. Java defines 4 types of integer, all signed.
byte - 8-bit integer from -128 to 127 (1 byte of storage)
short - 16-bit integer from -32,768 to 32,767 (2 bytes of storage)
int - 32-bit integer from -2,147,483,648 to 2,147,483,647 (4 bytes of storage)
long - 64-bit integer from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (8 bytes of storage)
Importantly, you can think of a byte as a storage of 8 independent flags, each of which can be turned on (1) or off (0).
If we map the byte (8 bits) in memory, the following is the integer value 0.
Bits ==> | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Values (0 or 1) ==> | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||||||||
Integer Values When 1 ==> | 128 (27) | 64 (26) | 32 (25) | 16 (24) | 8 (23) | 4 (22) | 2 (21) | 1 (20) |
As you can see, all combinations between 0 and 255 are possible if they are unsigned. When you form a number, you have to go from the highest bit (most significant) to the lowest (least significant). That is, from bit 7 to bit 0. Take 33, for example.
Bit 7? No 128 is higher than 33.
Bit 6? No 64 is higher than 33.
Bit 5? Yes 32 is lower than 33. When you minus 32, we're left with 1 which is the least significant bit of the byte.
Bits | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Values | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 |
Example for 240
Bits | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Values | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
Bit Mask
This is all very well, but the aim is to use each bit independently. For example, suppose we want to map a code on a byte (8-bit) that represents a record for a fabric shop:
3 Cloth categoriesCasual wear (1)Formal wear (2)Sports wear (3)3 ColorsBlue (1)White (2)Black (3)4 SizesSmall (1)Medium (2)Large (3)XL (4)
Cloth categories can be kept on 2 bit, since with 2 bit you can make the number 1 (01), 2 (10) or 3 (11). The same can be said forcolors. To store thesizes 2 bit is not enough, you need at least 3: 1 (001), 2 (010), 3 (011) and 4 (100).
Let's now map our byte to store all this information.
Bits ==> | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Values | _UNUSED_ | Size | Color | Cloth category |
So now let's code a casual wear (01), black (11) and size XL (100) => This gives a value of 77 (see map below)
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
How to get the bits in Java
Now that we have a number, we need to look at it as bit map. How do we isolate the bit 0 and 1 (category), bit 2 and 3 (color) and bit 4, 5 and 6 (size)? We can do it my masking and shifting. First, wemask to retrieve the bits in the byte, using the& operator. The mask is all of the bits, that we need from the byte, set to 1.
// Masking the categoryint category = mask & 3
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
category | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | |||||||||
mask | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
// Masking the colorint color = mask & 12
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
category | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | |||||||||
mask | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
// Masking the sizeint size = mask & 112
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
category | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | |||||||||
mask | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
Then we shift the bits to the right to get the value we want, using the>> (shift right) operator.
// Masking the categoryint category = (mask & 3)
No need to shiftcategory, it's already on the least significant part of the byte.
// Masking the colorint color = (mask & 12) >> 2
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Color | 0 | 0 | 0 | 0 | ==> 2 | 1 | 1 |
// Masking the sizeint size = (mask & 112) >> 4
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Size | 0 | ==> 4 | 1 | 0 | 0 |
In code
packageans.examples;publicclassBitsAndBytes{publicstaticfinalintWEAR_CASUAL=1;publicstaticfinalintWEAR_FORMAL=2;publicstaticfinalintWEAR_SPORT=3;publicstaticfinalintCOLOR_BLUE=1;publicstaticfinalintCOLOR_WHITE=2;publicstaticfinalintCOLOR_BLACK=3;publicstaticfinalintSIZE_SMALL=1;publicstaticfinalintSIZE_MEDIUM=2;publicstaticfinalintSIZE_LARGE=3;publicstaticfinalintSIZE_XL=4;publicstaticbytemakeCode(intwear,intcolor,intsize){return(byte)(wear+(color<<2)+(size<<4));}publicstaticintgetWear(bytecode){returncode&3;}publicstaticintgetColor(bytecode){return(code&12)>>2;}publicstaticintgetSize(bytecode){return(code&112)>>4;}publicstaticvoidmain(String[]args){bytecode=makeCode(WEAR_CASUAL,COLOR_BLACK,SIZE_XL);System.out.println("Causal Wear, Black, Size XL = "+code);switch(getWear(code)){caseWEAR_CASUAL:System.out.println("Casual wear");break;caseWEAR_FORMAL:System.out.println("Formal wear");break;caseWEAR_SPORT:System.out.println("Sport wear");break;default:System.out.println("Invalid wear code");break;}switch(getColor(code)){caseCOLOR_BLUE:System.out.println("Color Blue");break;caseCOLOR_WHITE:System.out.println("Color White");break;caseCOLOR_BLACK:System.out.println("Color Black");break;default:System.out.println("Invalid color code");break;}switch(getSize(code)){caseSIZE_SMALL:System.out.println("Size Small");break;caseSIZE_MEDIUM:System.out.println("Size Medium");break;caseSIZE_LARGE:System.out.println("Size large");break;caseSIZE_XL:System.out.println("Size XL");break;default:System.out.println("Invalid size code");break;}}}
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse