Monthly Archives: August 2014

Bits and pieces…

It’s been a while since I’ve posted, and for that I am sorry.  Life suddenly got busy, but here’s a post that’s been bubbling away the last few weeks.

One of the things I’ve always been blessed with (in some sense at least) is the knowledge of my weaknesses.  I’d argue that it’s a very important skill in a Software Engineer to know where their weaknesses lie.  I’m not talking about putting oneself down and making out that you know nothing.  Not at all, I’m talking about having sober judgement about your skills as a programmer.

So recently, I had cause to come across an area I’d never dabbled with as a programmer.  I’ve been doing some experimentation work on something that required me to have knowledge of bit-shifting and masking.

For those who were brought up in C, this is probably second nature to you, and you can safely switch off now.  I won’t be offended.  For the rest of you who are still with me, the inability to understand bit-shifting and masking is not something you should be ashamed of.  It wasn’t something I was taught at University (I did an Internet Computing degree).  It’s something I’ve had to learn fairly recently.

But before I get to some code (yes I know! actual code!!) I think it’s a good idea to go over bit-wise operators VERY quickly.

So you have a bitwise AND operator (&), a bitwise OR operator (|), a bitwise Complement opearator (~) which is also known as an inverse operator.  The AND and OR truth tables are shown below.

 image

The complement operator (~) essentially flips the bits, or inverses them, so you if you had:

000000001 in Binary, and put it through the (~) operator you’d get returned 11111110.

So now we know what the truth table looks like, let’s discuss bit-mapping.  This is generally used to check whether a certain bit is set or not.  It’s commonly used with uint8_t in C++ from what I’ve seen, however it can be used with other unsigned integer types as well.

So let’s say we want to simulate an 8 switch DIP switch.  I’m sure you’ve seen them underneath various electrical appliances.  In case you haven’t, here’s an example below.

As you can see, it has eight switches on it, which allows you to configure your hardware in a certain way.  It’s often seen in remote door bells etc.

So lets say you want to check that bit 1 is set, that is the left switch.  To do that you need to use a bitmask.  So a quick word is needed on binary numbers.  They start at 1, and go up by 2 each time, and you generally write the larger number on the left, and the lowest number on the right.  So for example, for an 8 bit number, the binary values are thus:

128, 64, 32, 16, 8, 4, 2,1 which all add up to 255.

So if we wanted to check that the 1st bit was set, we’d need to check that the bit furthest to the left was set, which in this case is the 128 value.  Bit masks tend to be written in Hex.  So using my Windows Calculator in programmer mode (no shame in that either by the way!!) The hex of 128 is 80.  But we also need to decide what sort of mask we’re going to use.

So if we want to check that the first bit is set in our switch, what sort of bitmask do we need?  An OR based one?  Or an AND based one?  In this instance we need to use an AND based mask.  So the mask in binary would look something like this:

10000000 so for example:

10000001 – Original value
10000000 – Our mask:
===================
10000000 – Result

The mask ONLY checks the bit or bits we’re interested in.  It ignores everything else.

So how do we represent that in code?

Well, like this:

bool checkBit(uint8_t value)
{
	bool returnValue = false;

	if((val & 0x80) == 0x80)
	{
		returnValue = true;
	}

	return returnValue;
}

So what’s going on here?  Well it’s a very simplistic program that simply tests that a bit is set using the bitmask.  So the if statement places a mask over the value, and compares it against the expected result.

So that’s a simple example.  Let’s say we want to print out a number in binary.  There isn’t an easy way to do this in C++, so we have to roll our own.  This brings bit shifting in to the mix.

Bit shifting is basically shifting a bit one way or the other.  There are two bitwise shift operators in C++, >> for a right bitwise shift, and a << for a left bitwise shift.  So to print a binary number from a normal number, we need to shift a bit, and using a mask, check if it’s a zero or a one.  Then based on that, add it to an output stream.  It sounds complicated, but it’s not that hard once you get the hang of it.

In code it looks a little something like this:

#include <iostream>
#include <sstream> // for stringstream

using namespace std;

// For now we print 8 bit numbers.
string printBinary(uint8_t val)
{
	stringstream outputStream;
	//uint8_t lastBit = 0x80;
	for(int i = 1 ; i <= 8; ++i)
	{
		// Check what we have in the first bit.
        if((val & 0x80) == 0x80)
		{
			outputStream << 1;
		}
		else
		{
			outputStream << 0;
		}
		// Now shift everything 1 to the left.
		val = val << 1;
	}
	return outputStream.str();
}

int main(int argc, char* argv[])
{
	if(argc != 2)
	{
		cout << "Usage: ./binPrint <number between 1 and 255>" << endl;
		return (1);
	}
	// We don't put an endl here as we want it on the same line.
	cout << "Printing out binary value of " << argv[1] << " : ";

	// Convert the char to a uint8_t
	uint8_t value = atoi(argv[1]);
	cout << printBinary(value) << endl;
	return (0);
}

So what does this code do?

Well, it loops over an 8 bit number checking what the first bit is.  Based on the result of the mask, it appends it to the end of a stringstream so that a formatted binary string is outputted.  So for example if I want to print out the number 8 in binary, it would come out as: 00001000.

Another thing to note is that we grab the value BEFORE we do the bit-wise shift.  And we’ve got to be careful when shifting to the left, becuase if we’re checking the first bit like we’re doing in the code here, then we could shift things off the end, so we’ve got to make sure we nab the bit we want and THEN dot he bitshift.

Please do feel free to play and have a go.  It’s honestly the best way to learn.  I’m in the process of re-writing my binary printer now to cope with any bit number from uint8_t to uint64_t which is quite a challenge.  I may post that up here once I’m done.

Advertisements