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
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