Static Zero

Writing What We Want

Static Zero header image 2

Convert Decimal to 2’s Complement Binary in C

April 24th, 2008 · 2 Comments · Programming

I was writing a program recently, and I needed a function that would convert a given decimal number to 2’s Complement (signed) binary. It’s simple enough to convert an unsigned integer to binary, but the sign (especially 2’s comp) makes it tricky. Since I couldn’t find a function to do this for me, I decided to write my own. It may not be the prettiest method, but it’s simple and effective.

First here’s a quick review of 2’s comp (Don’t know how to convert decimal to binary?):
Lets take a decimal number, say 5. Convert that to (signed) binary and we get 00101. Of course to get a negative binary number, we have to do a couple extra steps. Lets use -5 as the example. First, take the number 5 in binary, 00101. Then flip the bits to get 11010. However, that isnt quite right - that would be -6 in binary, so lets add 1 to get 11011. That is -5 in 2’s comp.

Here is a C function that will do this for you. The comments in the code should explain everything well enough (as I added them solely for that purpose). Also, see additional notes after the code.

Edit: For some reason, wordpress decided to display some of the decrement operators as a single dash. Replace any dashes with two hyphens and you should be fine. (Or download the full code at the bottom of this page).

/* This function will convert base 10 decimal to 2's
 * complement binary.
 */
int *decToBin(int decimal, int numBits, int binary[]) {
	int tmp, i;
	int carry = 1;
	int flag = 0;

	/* Indicies are 0 - numBits-1, so subtract 1 */
	tmp = --numBits;

	/* Initialize array to 0 */
	for(i=tmp; i>=0; i--)
		binary[i] = 0;

	/* If the number is negative, set the
	 * flag and invert the number
	 */
	if (decimal < 0) {
		flag = 1;
		decimal = -decimal;
	}

	/* decimal%2 will give the current binary bit.
	 * Divide by 2 to get the next bit.  Do this while
	 * decimal is larger than 0. (Note - integer division
	 * will throw away the remainder, which must happen.
	 */
	while (decimal > 0) {
		binary[numBits–] = decimal%2;
		decimal/=2;
	}

	/* Deal with the negative number.  First, take the
	 * complement of the current bit.  This number will
	 * be 2 less than the bit we want, so add 2.  Then
	 * add the carry.  If the result is > 1, it’s no
	 * longer binary, so set it to 0 and try the next
	 * bit.  Continue this until we can successfully add
	 * the carry bit. Once it is added, or once we’ve
	 * finished the loop, we’re done.
	 */
	if (flag) {
		for(i=tmp; i>=0; i–){
			binary[i] = ~(binary[i])+2;
			binary[i]+=carry;
			carry = 0;
			if (binary[i] > 1) {
				binary[i] = 0;
				carry = 1;
			}
		}
	}

	/* Return the array */
	return binary;
}

Notes:

  • This code does not return any overflow indicator. If you make your array one index larger, than the most significant bit can serve that purpose.
  • I use the name “numBits” to signify the number of bits in the binary conversion, not the actual number of bits that it takes to store the array on disk. Duh.
  • The most significant bit is stored in binary[0]. The reason I use this Big Endian format is so that when you go to access the array (say, to print it) the bits will appear in the correct (Little Endian) order.

Want a full, working version? d2b.c

Tags: ·

2 responses so far ↓

  • 1 Maphyday // May 7, 2008 at 5:26 pm

    Cool news!, man

  • 2 nick // May 25, 2008 at 8:29 pm

    Glad it was useful.

Leave a Comment