Display the binary representation of a number in C?
Solution 1
Yes (write your own), something like the following complete function.
#include <stdio.h> /* only needed for the printf() in main(). */
#include <string.h>
/* Create a string of binary digits based on the input value.
Input:
val: value to convert.
buff: buffer to write to must be >= sz+1 chars.
sz: size of buffer.
Returns address of string or NULL if not enough space provided.
*/
static char *binrep (unsigned int val, char *buff, int sz) {
char *pbuff = buff;
/* Must be able to store one character at least. */
if (sz < 1) return NULL;
/* Special case for zero to ensure some output. */
if (val == 0) {
*pbuff++ = '0';
*pbuff = '\0';
return buff;
}
/* Work from the end of the buffer back. */
pbuff += sz;
*pbuff-- = '\0';
/* For each bit (going backwards) store character. */
while (val != 0) {
if (sz-- == 0) return NULL;
*pbuff-- = ((val & 1) == 1) ? '1' : '0';
/* Get next bit. */
val >>= 1;
}
return pbuff+1;
}
Add this main to the end of it to see it in operation:
#define SZ 32
int main(int argc, char *argv[]) {
int i;
int n;
char buff[SZ+1];
/* Process all arguments, outputting their binary. */
for (i = 1; i < argc; i++) {
n = atoi (argv[i]);
printf("[%3d] %9d -> %s (from '%s')\n", i, n,
binrep(n,buff,SZ), argv[i]);
}
return 0;
}
Run it with "progname 0 7 12 52 123"
to get:
[ 1] 0 -> 0 (from '0')
[ 2] 7 -> 111 (from '7')
[ 3] 12 -> 1100 (from '12')
[ 4] 52 -> 110100 (from '52')
[ 5] 123 -> 1111011 (from '123')
Solution 2
There is no direct way (i.e. using printf
or another standard library function) to print it. You will have to write your own function.
/* This code has an obvious bug and another non-obvious one :) */
void printbits(unsigned char v) {
for (; v; v >>= 1) putchar('0' + (v & 1));
}
If you're using terminal, you can use control codes to print out bytes in natural order:
void printbits(unsigned char v) {
printf("%*s", (int)ceil(log2(v)) + 1, "");
for (; v; v >>= 1) printf("\x1b[2D%c",'0' + (v & 1));
}
Solution 3
Based on dirkgently's answer, but fixing his two bugs, and always printing a fixed number of digits:
void printbits(unsigned char v) {
int i; // for C89 compatability
for(i = 7; i >= 0; i--) putchar('0' + ((v >> i) & 1));
}
Solution 4
#include<iostream>
#include<conio.h>
#include<stdlib.h>
using namespace std;
void displayBinary(int n)
{
char bistr[1000];
itoa(n,bistr,2); //2 means binary u can convert n upto base 36
printf("%s",bistr);
}
int main()
{
int n;
cin>>n;
displayBinary(n);
getch();
return 0;
}
Solution 5
Use a lookup table, like:
char *table[16] = {"0000", "0001", .... "1111"};
then print each nibble like this
printf("%s%s", table[a / 0x10], table[a % 0x10]);
Surely you can use just one table, but it will be marginally faster and too big.
Paul Wicks
Updated on July 18, 2022Comments
-
Paul Wicks almost 2 years
Possible Duplicate:
Is there a printf converter to print in binary format?Still learning C and I was wondering:
Given a number, is it possible to do something like the following?
char a = 5; printf("binary representation of a = %b",a); > 101
Or would i have to write my own method to do the transformation to binary?
-
visual_learner about 15 yearsNice bit hacks. Unreadable code FTW!
-
dirkgently about 15 years@Chris Lutz: Actually, this is as simple as they come :-)
-
abelenky about 15 years@Chris Lutz: I agree with dirkgently. The function is well named, and clearly written in a linear fashion. Each statement is simple and obvious.
-
paxdiablo about 15 yearsYeah, not sure I'd be inflicting this monstrosity :-) on someone "Still learning C". Still, it works.
-
visual_learner about 15 yearsI upvoted, and actually do like the solution. I just am also a bit sarcastic sometimes. Sorry it seemed like I thought it was bad. I think it's quite readable, if you know bitwise operations. Which a lot of people unfortunately don't. (Also, the >>= and <<= operators just look a bit silly to me.)
-
Kevin Lacquement about 15 yearsYou missed the case where the input is 0, which will print nothing in this case.
-
dirkgently about 15 years@Pax: Do you equate terseness with monstrosity? Alas, any student of C has to live with such monstrosity, for that is the C way of life. The earlier they learn, the better it is.
-
dirkgently about 15 years@Chris Lutz: +2; It was the other way round for me though :)
-
unwind about 15 yearsVery confusing to show a string function in C that takes a buffer size as input, and doesn't use that size in a defensive (enough) manner. For sz == 0 && x == 0, it will still write "0" to the buffer.
-
Jonathan Leffler about 15 yearsThe other bug is that it only prints out for a byte at a time, not for 32-bit or 64-bit values. Though, since the question was about printing a 'char', maybe that doesn't matter.
-
dirkgently about 15 years@unwind: Which buffer size parameter are you talking about?
-
Jonathan Leffler about 15 yearsI see a buffer underflow if the binrep() function is not given enough space for the value it is printing. And, speaking from bitter (but long ago) experience, stuff writing off the front of an array can be really nasty to debug!
-
paxdiablo about 15 yearsYes, that will be troublesome - if your ints are more than 32 bits, you have to make sure you increase SZ to suit.
-
paxdiablo about 15 years@dirk, I gather that buffer size comment was meant for my answer.
-
Leon about 15 yearsAs icing on the cake you could also replace i = 7 with (sizeof(v)*8)-1
-
dirkgently about 15 years@Pax: Oh, well, so I gathered :-) Just wanted a confirmation from unwind.
-
paxdiablo about 15 yearsFixed to prevent the buffer overflow.
-
paxdiablo about 15 yearsQuote: "buff: buffer to write to must be >= sz+1 chars." - sz is the size of the buffer, excluding the terminating null.
-
unwind about 15 years@Pax: Oh, okay ... I'll delete my comment. I get queasy when exposed to a function taking a string size argument that is incompatible with a simple sizeof; requiring me to remember to add or subtract 1 is not cool, in my opinion.
-
paxdiablo about 15 yearsWell, it has precedent, in fgets(), so I guess it's not a total anti-pattern.
-
visual_learner about 15 yearsI'd do that if I could find a way to make the function take an argument of any type, rather than just an unsigned char. I tried using a void pointer, but I'm getting errors. I'll need to look into that more sometime though.
-
David Xia over 12 yearsthis worked for me:char* printbits(int v) { for(int i = (sizeof(v)*8)-1; i >= 0; i--) putchar('0' + ((v >> i) & 1)); }
-
David Xia over 12 yearsIs there a way to have it return char*?
-
visual_learner over 12 years@David - Of course there is. Google around for other questions related to this. (Or ask your own, but I bet it's a duplicate.) You'll probably need to use
malloc
. -
David 天宇 Wong over 10 yearsI still don't understand this "for"
-
dotancohen about 9 yearsI will start adding that comment to some methods of mine that I know that I have not properly debugged. For myself it will be a reminder. For others, it will be a warning.
-
DanSkeel about 9 yearsAlso consider
i = v ? (int)floor(log2(v)) : 0