Convert decimal to binary in C - c

I am trying to convert a decimal to binary such as 192 to 11000000. I just need some simple code to do this but the code I have so far doesn't work:
void dectobin(int value, char* output)
{
int i;
output[5] = '\0';
for (i = 4; i >= 0; --i, value >>= 1)
{
output[i] = (value & 1) + '0';
}
}
Any help would be much appreciated!

The value is not decimal. All values in computer's memory are binary.
What you are trying to do is to convert int to a string using specific base.
There's a function for that, it's called itoa.
http://www.cplusplus.com/reference/cstdlib/itoa/

First of all 192cannot be represented in 4 bits
192 = 1100 0000 which required minimum 8 bits.
Here is a simple C program to convert Decimal number system to Binary number system
#include <stdio.h>
#include <string.h>
int main()
{
long decimal, tempDecimal;
char binary[65];
int index = 0;
/*
* Reads decimal number from user
*/
printf("Enter any decimal value : ");
scanf("%ld", &decimal);
/* Copies decimal value to temp variable */
tempDecimal = decimal;
while(tempDecimal!=0)
{
/* Finds decimal%2 and adds to the binary value */
binary[index] = (tempDecimal % 2) + '0';
tempDecimal /= 2;
index++;
}
binary[index] = '\0';
/* Reverse the binary value found */
strrev(binary);
printf("\nDecimal value = %ld\n", decimal);
printf("Binary value of decimal = %s", binary);
return 0;
}

5 digits are not enough for your example (192). Probably you should increase output

A few days ago, I was searching for fast and portable way of doing sprintf("%d", num). Found this implementation at the page itoa with GCC:
/**
* C++ version 0.4 char* style "itoa":
* Written by Lukás Chmela
* Released under GPLv3.
*/
char* itoa(int value, char* result, int base) {
// check that the base if valid
if (base < 2 || base > 36) { *result = '\0'; return result; }
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while ( value );
// Apply negative sign
if (tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return result;
}

It looks like this, but be careful, you have to reverse the resulting string :-)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char output[256]="";
int main()
{
int x= 192;
int n;
n = x;
int r;
do {
r = n % 2;
if (r == 1)
strcat(output,"1");
else strcat(output,"0");
n = n / 2;
}
while (n > 0);
printf("%s\n",output);
}

So... did you check the output of your code to understand why it doesn't work?
So iteration 1 of your loop:
value = 192
i = 4
output[i] = (11000000 & 1) + '0' = 0 + 48 = 48 (char `0`)
Iteration 2 of your loop:
value = 96
i = 3
output[i] = (1100000 & 1) + '0' = 0 + 48 = 48 (char `0`)
Iteration 3 of your loop:
value = 48
i = 2
output[i] = (110000 & 1) + '0' = 0 + 48 = 48 (char `0`)
Iteration 4 of your loop:
value = 24
i = 1
output[i] = (11000 & 1) + '0' = 0 + 48 = 48 (char `0`)
Iteration 5 of your loop:
value = 12
i = 0
output[i] = (1100 & 1) + '0' = 0 + 48 = 48 (char `0`)
Final string: "00000" and you wanted: "11000000"
See anything wrong with your code? Nope. Neither do I you just didn't go far enough. Change your output/loop to:
output[8] = '\0';
for (i = 7; i >= 0; --i, value >>= 1)
And then you'll have the correct result returned.
I would recomend just a more general approach, you're using a fixed length string, which limits you to binary numbers of a certian length. You might want to do something like:
loop while number dividing down is > 0
count number of times we loop
malloc an array the correct length and be returned

#include <stdio.h>
#include <stdlib.h>
void bin(int num) {
int n = num;
char *s = malloc(sizeof(int) * 8);
int i, c = 0;
printf("%d\n", num);
for (i = sizeof(int) * 8 - 1; i >= 0; i--) {
n = num >> i;
*(s + c) = (n & 1) ? '1' : '0';
c++;
}
*(s + c) = NULL;
printf("%s", s); // or you can also return the string s and then free it whenever needed
}
int main(int argc, char *argv[]) {
bin(atoi(argv[1]));
return EXIT_SUCCESS;
}

You can do it using while loop under a function also. I was just searching the solve for mine but the solves i get were not suitable, so I have done it accordingly the practical approach (divide using 2 until getting 0 and store the reminder in an array) and print the reverse of the array and Shared Here
#include <stdio.h>
int main()
{
long long int a,c;
int i=0,count=0;
char bol[10000];
scanf("%lld", &a);
c = a;
while(a!=0)
{
bol[i] = a%2;
a = a / 2;
count++;
i++;
}
if(c==0)
{
printf("0");
}
else
{
for(i=count-1; i>=0; i--)
{
printf("%d", bol[i]);
}
}
printf("\n");
return 0;
}

//C Program to convert Decimal to binary using Stack
#include<stdio.h>
#define max 100
int stack[max],top=-1,i,x;
void push (int x)
{
++top;
stack [top] = x;
}
int pop ()
{
return stack[top];
}
void main()
{
int num, total = 0,item;
print f( "Please enter a decimal: ");
scanf("%d",&num);
while(num > 0)
{
total = num % 2;
push(total);
num /= 2;
}
for(i=top;top>-1;top--)
{
item = pop ();
print f("%d",item);
}
}

Convert Decimal to Binary in C Language
#include<stdio.h>
void main()
{
long int n,n1,m=1,rem,ans=0;
printf("\nEnter Your Decimal No (between 0 to 1023) :: ");
scanf("%ld",&n);
n1=n;
while(n>0)
{
rem=n%2;
ans=(rem*m)+ans;
n=n/2;
m=m*10;
}
printf("\nYour Decimal No is :: %ld",n1);
printf("\nConvert into Binary No is :: %ld",ans);
}

This is the simplest way to do it
#include <stdio.h>
void main()
{
int n,i,j,sum=0;
printf("Enter a Decimal number to convert it to binary : ");
scanf("%d",&n);
for(i=n,j=1;i>=1;j*=10,i/=2)
sum+=(i%2)*j;
printf("\n%d",sum);
}

This is a simple program to convert a number from decimal to binary
#include <stdio.h>
#include <conio.h>
void decToBinary(int);
int main()
{
int number;
printf("Enter number to convert to binary: ");
scanf("%d", &number);
decToBinary(number);
return 0;
}
void decToBinary(int num)
{
if (num == 0)
{
return ;
}
decToBinary(num / 2);
printf("%d", num % 2);
}
Output of the Program:

Perhaps understanding the algorithm would allow you write or modify your own code to suit what you need. I do see that you don't have enough char array length to display your binary value for 192 though (You need 8 digits of binary, but your code only gives 5 binary digits)
Here's a page that clearly explains the algorithm.
I'm not a C/C++ programmer so here's my C# code contribution based on the algorithm example.
int I = 0;
int Q = 95;
string B = "";
while (Q != 0)
{
Debug.Print(I.ToString());
B += (Q%2);
Q = Q/2;
Debug.Print(Q.ToString());
I++;
}
Debug.Print(B);
All the Debug.Print is just to show the output.

//decimal to binary converter
long int dec2bin(unsigned int decimal_number){
if (decimal_number == 0)
return 0;
else
return ((decimal_number%2) + 10 * dec2bin(decimal_number/2));
}

number=215
a=str(int(number//128>=1))+str(int(number%128>=64))+
str(int(((number%128)%64)>=32))+str(int((((number%12
8)%64)%32)>=16))+str(int(((((number%128)%64)%32)%16)>=8))
+str(int(((((((number%128)%64)%32)%16)%8)>=4)))
+str(int(((((((((number%128)%64)%32)%16)%8)%4)>=2))))
+str(int(((((((((((number%128)%64)%32)%16)%8)%4)%2)>=1)))))
print(a)
You can also use the 'if', 'else', statements to write this code.

int main()
{
int n, c, k;
printf("Enter an integer in decimal number system: ");
scanf("%d", &n);
printf("%d in binary number system is: ", n);
for (c = n; c > 0; c = c/2)
{
k = c % 2;//To
k = (k > 0) ? printf("1") : printf("0");
}
getch();
return 0;
}

Related

Calculating sum of certain previously inputted numbers

This program should calculate the sum of all numbers whose digits are in descending order. It stops you from inputting if the number isn't a whole number. I think that the problem might be because of the sum variable, but I don't know how to fix it.
Edit: Per #user3386109 request, here is the output I get:
4321
75
56
4,79
0
The sum should be 4396, as sum of 4321 and 75. Not 0.
Sorry for the unclear question I am quite new to this.
int n, last, secondlast, sum, c = 0;
int temp;
while (scanf("%d", &n) == 1) {
sum = 0;
while (temp > 0) {
last = temp % 10;
secondlast = (temp / 10) % 10;
if (secondlast > last) {
c++;
sum = sum + temp;
}
temp = temp / 10;
}
}
if (c == 0) {
printf("There are no numbers that meet the requirements\n");
}
else {
printf("%d\n", sum);
}
As #Support Ukraine commented, this code gets the job done.
#include <stdio.h>
int descendingDigits(int n)
{
int current = n % 10;
n = n / 10;
while(n)
{
int this = n % 10;
if (this <= current) return 0;
current = this;
n = n / 10;
}
return 1;
}
int main(void) {
int sum = 0;
int c = 0;
int n = 0;
while (scanf("%d", &n) == 1) {
if (descendingDigits(n))
{
sum = sum + n;
c = 1;
}
}
if (c == 0) {
printf("There are no numbers that meet the requirements\n");
}
else
{
printf("%d\n", sum);
}
return 0;
}
%10 operations are really not the best way to determine if the digits are descending. It works, but it seems like overkill to use scanf to convert the input to an integer at all, since it's much easier to know if the digits are in order if you leave them as a string. It's tempting to check if the digits of the string are descending and only convert to an integer value if they are, but it seems like a bad idea to parse the string twice. In other words; read the input as a string and do not convert, then compute the integer value while you are looking at the digits to see if they are descending. This is aesthetically appealing, since you minimize computations. (eg, if the input string is "47901", you shouldn't waste cpu cycles converting that to the integer 47901; after you see that 7 is not less than 4, you can abort).
eg:
#include <ctype.h>
#include <stdio.h>
/* If the string s represents an integer
* with (strictly) descending digits, return
* its integer representation (base 10). Else
* return 0.
*/
unsigned
is_descending(const char *s)
{
unsigned rv = 0;
int last = '9' + 1;
while( *s ){
if( isdigit(*s) && *s < last ){
rv = 10 * rv + *s - '0';
} else {
return 0;
}
last = *s++;
}
return rv;
}
int
main(int argc, char **argv)
{
char buf[64];
unsigned sum = 0;
while( scanf("%63s", buf) == 1 ){
sum += is_descending(buf);
}
printf("sum: %u\n", sum);
return 0;
}
Note that this does not handle negative numbers well, but it's not clear how you want to deal with that. Left as an exercise for the reader.

How can print string num?

Problem:
How can print string num? It seems that final statement cannot execute?
Question desciptions:
Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, with no duplication. Double it we will obtain 246913578, which happens to be another 9-digit number consisting exactly the numbers from 1 to 9, only in a different permutation. Check to see the result if we double it again!
Now you are suppose to check if there are more numbers with this property. That is, double a given number with k digits, you are to tell if the resulting number consists of only a permutation of the digits in the original number.
/* Have Fun with Numbers */
#include <stdio.h>
#include <string.h>
int book[10] = { 0 };
int main(int argc, char* argv[])
{
char num[22];
int temp = 0;
scanf_s("%s", num, 1);
// Length of numbers
int len = strlen(num);
int flag = 0;
for (int i = len - 1; i >= 0; --i) {
// Convert an ASCII value of a digit into an integer
temp = num[i] - '0';
// Add 1 each time read a digit
++book[temp];
temp = temp * 2 + flag;
flag = 0;
if (temp >= 10) {
temp -= 10;
flag = 1;
}
// Convert an integer into an ASCII value of a digit
num[i] = (temp + '0');
// Subtract 1 each time generate a digit
--book[temp];
}
int flag1 = 0;
for (int i = 0; i < 10; ++i) {
if (book[i] != 0) {
flag1 = 1;
}
}
printf("%s", (flag == 1 || flag1 == 1) ? "No\n" : "Yes\n");
if (flag == 1) {
printf("1");
}
printf("%s", num);
return 0;
}
In this like
scanf_s("%s", num, 1);
You are reporting the buffer size as 1 to scanf_s() while the actual size is 22.
Use correct buffer size.
scanf_s("%s", num, 22);
or
scanf_s("%s", num, (unsigned)(sizeof(num) / sizeof(*num)));

How to format number adding points between each 3 numbers [duplicate]

In C, how can I format a large number from e.g. 1123456789 to 1,123,456,789?
I tried using printf("%'10d\n", 1123456789), but that doesn't work.
Could you advise anything? The simpler the solution the better.
If your printf supports the ' flag (as required by POSIX 2008 printf()), you can probably do it just by setting your locale appropriately. Example:
#include <stdio.h>
#include <locale.h>
int main(void)
{
setlocale(LC_NUMERIC, "");
printf("%'d\n", 1123456789);
return 0;
}
And build & run:
$ ./example
1,123,456,789
Tested on Mac OS X & Linux (Ubuntu 10.10).
You can do it recursively as follows (beware INT_MIN if you're using two's complement, you'll need extra code to manage that):
void printfcomma2 (int n) {
if (n < 1000) {
printf ("%d", n);
return;
}
printfcomma2 (n/1000);
printf (",%03d", n%1000);
}
void printfcomma (int n) {
if (n < 0) {
printf ("-");
n = -n;
}
printfcomma2 (n);
}
A summmary:
User calls printfcomma with an integer, the special case of negative numbers is handled by simply printing "-" and making the number positive (this is the bit that won't work with INT_MIN).
When you enter printfcomma2, a number less than 1,000 will just print and return.
Otherwise the recursion will be called on the next level up (so 1,234,567 will be called with 1,234, then 1) until a number less than 1,000 is found.
Then that number will be printed and we'll walk back up the recursion tree, printing a comma and the next number as we go.
There is also the more succinct version though it does unnecessary processing in checking for negative numbers at every level (not that this will matter given the limited number of recursion levels). This one is a complete program for testing:
#include <stdio.h>
void printfcomma (int n) {
if (n < 0) {
printf ("-");
printfcomma (-n);
return;
}
if (n < 1000) {
printf ("%d", n);
return;
}
printfcomma (n/1000);
printf (",%03d", n%1000);
}
int main (void) {
int x[] = {-1234567890, -123456, -12345, -1000, -999, -1,
0, 1, 999, 1000, 12345, 123456, 1234567890};
int *px = x;
while (px != &(x[sizeof(x)/sizeof(*x)])) {
printf ("%-15d: ", *px);
printfcomma (*px);
printf ("\n");
px++;
}
return 0;
}
and the output is:
-1234567890 : -1,234,567,890
-123456 : -123,456
-12345 : -12,345
-1000 : -1,000
-999 : -999
-1 : -1
0 : 0
1 : 1
999 : 999
1000 : 1,000
12345 : 12,345
123456 : 123,456
1234567890 : 1,234,567,890
An iterative solution for those who don't trust recursion (although the only problem with recursion tends to be stack space which will not be an issue here since it'll only be a few levels deep even for a 64-bit integer):
void printfcomma (int n) {
int n2 = 0;
int scale = 1;
if (n < 0) {
printf ("-");
n = -n;
}
while (n >= 1000) {
n2 = n2 + scale * (n % 1000);
n /= 1000;
scale *= 1000;
}
printf ("%d", n);
while (scale != 1) {
scale /= 1000;
n = n2 / scale;
n2 = n2 % scale;
printf (",%03d", n);
}
}
Both of these generate 2,147,483,647 for INT_MAX.
All the code above is for comma-separating three-digit groups but you can use other characters as well, such as a space:
void printfspace2 (int n) {
if (n < 1000) {
printf ("%d", n);
return;
}
printfspace2 (n/1000);
printf (" %03d", n%1000);
}
void printfspace (int n) {
if (n < 0) {
printf ("-");
n = -n;
}
printfspace2 (n);
}
Here's a very simple implementation. This function contains no error checking, buffer sizes must be verified by the caller. It also does not work for negative numbers. Such improvements are left as an exercise for the reader.
void format_commas(int n, char *out)
{
int c;
char buf[20];
char *p;
sprintf(buf, "%d", n);
c = 2 - strlen(buf) % 3;
for (p = buf; *p != 0; p++) {
*out++ = *p;
if (c == 1) {
*out++ = ',';
}
c = (c + 1) % 3;
}
*--out = 0;
}
Egads! I do this all the time, using gcc/g++ and glibc on linux and yes, the ' operator may be non-standard, but I like the simplicity of it.
#include <stdio.h>
#include <locale.h>
int main()
{
int bignum=12345678;
setlocale(LC_ALL,"");
printf("Big number: %'d\n",bignum);
return 0;
}
Gives output of:
Big number: 12,345,678
Just have to remember the 'setlocale' call in there, otherwise it won't format anything.
Perhaps a locale-aware version would be interesting.
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <limits.h>
static int next_group(char const **grouping) {
if ((*grouping)[1] == CHAR_MAX)
return 0;
if ((*grouping)[1] != '\0')
++*grouping;
return **grouping;
}
size_t commafmt(char *buf, /* Buffer for formatted string */
int bufsize, /* Size of buffer */
long N) /* Number to convert */
{
int i;
int len = 1;
int posn = 1;
int sign = 1;
char *ptr = buf + bufsize - 1;
struct lconv *fmt_info = localeconv();
char const *tsep = fmt_info->thousands_sep;
char const *group = fmt_info->grouping;
char const *neg = fmt_info->negative_sign;
size_t sep_len = strlen(tsep);
size_t group_len = strlen(group);
size_t neg_len = strlen(neg);
int places = (int)*group;
if (bufsize < 2)
{
ABORT:
*buf = '\0';
return 0;
}
*ptr-- = '\0';
--bufsize;
if (N < 0L)
{
sign = -1;
N = -N;
}
for ( ; len <= bufsize; ++len, ++posn)
{
*ptr-- = (char)((N % 10L) + '0');
if (0L == (N /= 10L))
break;
if (places && (0 == (posn % places)))
{
places = next_group(&group);
for (int i=sep_len; i>0; i--) {
*ptr-- = tsep[i-1];
if (++len >= bufsize)
goto ABORT;
}
}
if (len >= bufsize)
goto ABORT;
}
if (sign < 0)
{
if (len >= bufsize)
goto ABORT;
for (int i=neg_len; i>0; i--) {
*ptr-- = neg[i-1];
if (++len >= bufsize)
goto ABORT;
}
}
memmove(buf, ++ptr, len + 1);
return (size_t)len;
}
#ifdef TEST
#include <stdio.h>
#define elements(x) (sizeof(x)/sizeof(x[0]))
void show(long i) {
char buffer[32];
commafmt(buffer, sizeof(buffer), i);
printf("%s\n", buffer);
commafmt(buffer, sizeof(buffer), -i);
printf("%s\n", buffer);
}
int main() {
long inputs[] = {1, 12, 123, 1234, 12345, 123456, 1234567, 12345678 };
for (int i=0; i<elements(inputs); i++) {
setlocale(LC_ALL, "");
show(inputs[i]);
}
return 0;
}
#endif
This does have a bug (but one I'd consider fairly minor). On two's complement hardware, it won't convert the most-negative number correctly, because it attempts to convert a negative number to its equivalent positive number with N = -N; In two's complement, the maximally negative number doesn't have a corresponding positive number, unless you promote it to a larger type. One way to get around this is by promoting the number the corresponding unsigned type (but it's is somewhat non-trivial).
Without recursion or string handling, a mathematical approach:
#include <stdio.h>
#include <math.h>
void print_number( int n )
{
int order_of_magnitude = (n == 0) ? 1 : (int)pow( 10, ((int)floor(log10(abs(n))) / 3) * 3 ) ;
printf( "%d", n / order_of_magnitude ) ;
for( n = abs( n ) % order_of_magnitude, order_of_magnitude /= 1000;
order_of_magnitude > 0;
n %= order_of_magnitude, order_of_magnitude /= 1000 )
{
printf( ",%03d", abs(n / order_of_magnitude) ) ;
}
}
Similar in principle to Pax's recursive solution, but by calculating the order of magnitude in advance, recursion is avoided (at some considerable expense perhaps).
Note also that the actual character used to separate thousands is locale specific.
Edit:See #Chux's comments below for improvements.
Based on #Greg Hewgill's, but takes negative numbers into account and returns the string size.
size_t str_format_int_grouped(char dst[16], int num)
{
char src[16];
char *p_src = src;
char *p_dst = dst;
const char separator = ',';
int num_len, commas;
num_len = sprintf(src, "%d", num);
if (*p_src == '-') {
*p_dst++ = *p_src++;
num_len--;
}
for (commas = 2 - num_len % 3;
*p_src;
commas = (commas + 1) % 3)
{
*p_dst++ = *p_src++;
if (commas == 1) {
*p_dst++ = separator;
}
}
*--p_dst = '\0';
return (size_t)(p_dst - dst);
}
Needed to do something similar myself but rather than printing directly, needed to go to a buffer. Here's what I came up with. Works backwards.
unsigned int IntegerToCommaString(char *String, unsigned long long Integer)
{
unsigned int Digits = 0, Offset, Loop;
unsigned long long Copy = Integer;
do {
Digits++;
Copy /= 10;
} while (Copy);
Digits = Offset = ((Digits - 1) / 3) + Digits;
String[Offset--] = '\0';
Copy = Integer;
Loop = 0;
do {
String[Offset] = '0' + (Copy % 10);
if (!Offset--)
break;
if (Loop++ % 3 == 2)
String[Offset--] = ',';
Copy /= 10;
} while (1);
return Digits;
}
Be aware that it's only designed for unsigned integers and you must ensure that the buffer is large enough.
There's no real simple way to do this in C. I would just modify an int-to-string function to do it:
void format_number(int n, char * out) {
int i;
int digit;
int out_index = 0;
for (i = n; i != 0; i /= 10) {
digit = i % 10;
if ((out_index + 1) % 4 == 0) {
out[out_index++] = ',';
}
out[out_index++] = digit + '0';
}
out[out_index] = '\0';
// then you reverse the out string as it was converted backwards (it's easier that way).
// I'll let you figure that one out.
strrev(out);
}
My answer does not format the result exactly like the illustration in the question, but may fulfill the actual need in some cases with a simple one-liner or macro. One can extend it to generate more thousand-groups as necessary.
The result will look for example as follows:
Value: 0'000'012'345
The code:
printf("Value: %llu'%03lu'%03lu'%03lu\n", (value / 1000 / 1000 / 1000), (value / 1000 / 1000) % 1000, (value / 1000) % 1000, value % 1000);
#include <stdio.h>
void punt(long long n){
char s[28];
int i = 27;
if(n<0){n=-n; putchar('-');}
do{
s[i--] = n%10 + '0';
if(!(i%4) && n>9)s[i--]='.';
n /= 10;
}while(n);
puts(&s[++i]);
}
int main(){
punt(2134567890);
punt(987);
punt(9876);
punt(-987);
punt(-9876);
punt(-654321);
punt(0);
punt(1000000000);
punt(0x7FFFFFFFFFFFFFFF);
punt(0x8000000000000001); // -max + 1 ...
}
My solution uses a . instead of a ,
It is left to the reader to change this.
This is old and there are plenty of answers but the question was not "how can I write a routine to add commas" but "how can it be done in C"? The comments pointed to this direction but on my Linux system with GCC, this works for me:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main()
{
unsetenv("LC_ALL");
setlocale(LC_NUMERIC, "");
printf("%'lld\n", 3141592653589);
}
When this is run, I get:
$ cc -g comma.c -o comma && ./comma
3,141,592,653,589
If I unset the LC_ALL variable before running the program the unsetenv is not necessary.
Another solution, by saving the result into an int array, maximum size of 7 because the long long int type can handle numbers in the range 9,223,372,036,854,775,807 to -9,223,372,036,854,775,807. (Note it is not an unsigned value).
Non-recursive printing function
static void printNumber (int numbers[8], int loc, int negative)
{
if (negative)
{
printf("-");
}
if (numbers[1]==-1)//one number
{
printf("%d ", numbers[0]);
}
else
{
printf("%d,", numbers[loc]);
while(loc--)
{
if(loc==0)
{// last number
printf("%03d ", numbers[loc]);
break;
}
else
{ // number in between
printf("%03d,", numbers[loc]);
}
}
}
}
main function call
static void getNumWcommas (long long int n, int numbers[8])
{
int i;
int negative=0;
if (n < 0)
{
negative = 1;
n = -n;
}
for(i = 0; i < 7; i++)
{
if (n < 1000)
{
numbers[i] = n;
numbers[i+1] = -1;
break;
}
numbers[i] = n%1000;
n/=1000;
}
printNumber(numbers, i, negative);// non recursive print
}
testing output
-9223372036854775807: -9,223,372,036,854,775,807
-1234567890 : -1,234,567,890
-123456 : -123,456
-12345 : -12,345
-1000 : -1,000
-999 : -999
-1 : -1
0 : 0
1 : 1
999 : 999
1000 : 1,000
12345 : 12,345
123456 : 123,456
1234567890 : 1,234,567,890
9223372036854775807 : 9,223,372,036,854,775,807
In main() function:
int numberSeparated[8];
long long int number = 1234567890LL;
getNumWcommas(number, numberSeparated);
If printing is all that's needed then move int numberSeparated[8]; inside the function getNumWcommas and call it this way getNumWcommas(number).
Another iterative function
int p(int n) {
if(n < 0) {
printf("-");
n = -n;
}
int a[sizeof(int) * CHAR_BIT / 3] = { 0 };
int *pa = a;
while(n > 0) {
*++pa = n % 1000;
n /= 1000;
}
printf("%d", *pa);
while(pa > a + 1) {
printf(",%03d", *--pa);
}
}
Here is the slimiest, size and speed efficient implementation of this kind of decimal digit formating:
const char *formatNumber (
int value,
char *endOfbuffer,
bool plus)
{
int savedValue;
int charCount;
savedValue = value;
if (unlikely (value < 0))
value = - value;
*--endOfbuffer = 0;
charCount = -1;
do
{
if (unlikely (++charCount == 3))
{
charCount = 0;
*--endOfbuffer = ',';
}
*--endOfbuffer = (char) (value % 10 + '0');
}
while ((value /= 10) != 0);
if (unlikely (savedValue < 0))
*--endOfbuffer = '-';
else if (unlikely (plus))
*--endOfbuffer = '+';
return endOfbuffer;
}
Use as following:
char buffer[16];
fprintf (stderr, "test : %s.", formatNumber (1234567890, buffer + 16, true));
Output:
test : +1,234,567,890.
Some advantages:
Function taking end of string buffer because of reverse ordered formatting. Finally, where is no need in revering generated string (strrev).
This function produces one string that can be used in any algo after. It not depends nor require multiple printf/sprintf calls, which is terrible slow and always context specific.
Minimum number of divide operators (/, %).
Secure format_commas, with negative numbers:
Because VS < 2015 doesn't implement snprintf, you need to do this
#if defined(_WIN32)
#define snprintf(buf,len, format,...) _snprintf_s(buf, len,len, format, __VA_ARGS__)
#endif
And then
char* format_commas(int n, char *out)
{
int c;
char buf[100];
char *p;
char* q = out; // Backup pointer for return...
if (n < 0)
{
*out++ = '-';
n = abs(n);
}
snprintf(buf, 100, "%d", n);
c = 2 - strlen(buf) % 3;
for (p = buf; *p != 0; p++) {
*out++ = *p;
if (c == 1) {
*out++ = '\'';
}
c = (c + 1) % 3;
}
*--out = 0;
return q;
}
Example usage:
size_t currentSize = getCurrentRSS();
size_t peakSize = getPeakRSS();
printf("Current size: %d\n", currentSize);
printf("Peak size: %d\n\n\n", peakSize);
char* szcurrentSize = (char*)malloc(100 * sizeof(char));
char* szpeakSize = (char*)malloc(100 * sizeof(char));
printf("Current size (f): %s\n", format_commas((int)currentSize, szcurrentSize));
printf("Peak size (f): %s\n", format_commas((int)currentSize, szpeakSize));
free(szcurrentSize);
free(szpeakSize);
A modified version of #paxdiablo solution, but using WCHAR and wsprinf:
static WCHAR buffer[10];
static int pos = 0;
void printfcomma(const int &n) {
if (n < 0) {
wsprintf(buffer + pos, TEXT("-"));
pos = lstrlen(buffer);
printfcomma(-n);
return;
}
if (n < 1000) {
wsprintf(buffer + pos, TEXT("%d"), n);
pos = lstrlen(buffer);
return;
}
printfcomma(n / 1000);
wsprintf(buffer + pos, TEXT(",%03d"), n % 1000);
pos = lstrlen(buffer);
}
void my_sprintf(const int &n)
{
pos = 0;
printfcomma(n);
}
I'm new in C programming. Here is my simple code.
int main()
{
// 1223 => 1,223
int n;
int a[10];
printf(" n: ");
scanf_s("%d", &n);
int i = 0;
while (n > 0)
{
int temp = n % 1000;
a[i] = temp;
n /= 1000;
i++;
}
for (int j = i - 1; j >= 0; j--)
{
if (j == 0)
{
printf("%d.", a[j]);
}
else printf("%d,",a[j]);
}
getch();
return 0;
}
Require: <stdio.h> + <string.h>.
Advantage: short, readable, based on the format of scanf-family. And assume no comma on the right of decimal point.
void add_commas(char *in, char *out) {
int len_in = strlen(in);
int len_int = -1; /* len_int(123.4) = 3 */
for (int i = 0; i < len_in; ++i) if (in[i] == '.') len_int = i;
int pos = 0;
for (int i = 0; i < len_in; ++i) {
if (i>0 && i<len_int && (len_int-i)%3==0)
out[pos++] = ',';
out[pos++] = in[i];
}
out[pos] = 0; /* Append the '\0' */
}
Example, to print a formatted double:
#include <stdio.h>
#include <string.h>
#define COUNT_DIGIT_MAX 100
int main() {
double sum = 30678.7414;
char input[COUNT_DIGIT_MAX+1] = { 0 }, output[COUNT_DIGIT_MAX+1] = { 0 };
snprintf(input, COUNT_DIGIT_MAX, "%.2f", sum/12);
add_commas(input, output);
printf("%s\n", output);
}
Output:
2,556.56
Using C++'s std::string as return value with possibly the least overhead and not using any std library functions (sprintf, to_string, etc.).
string group_digs_c(int num)
{
const unsigned int BUF_SIZE = 128;
char buf[BUF_SIZE] = { 0 }, * pbuf = &buf[BUF_SIZE - 1];
int k = 0, neg = 0;
if (num < 0) { neg = 1; num = num * -1; };
while(num)
{
if (k > 0 && k % 3 == 0)
*pbuf-- = ',';
*pbuf-- = (num % 10) + '0';
num /= 10;
++k;
}
if (neg)
*pbuf = '-';
else
++pbuf;
int cc = buf + BUF_SIZE - pbuf;
memmove(buf, pbuf, cc);
buf[cc] = 0;
string rv = buf;
return rv;
}
Here is a simple portable solution relying on sprintf:
#include <stdio.h>
// assuming out points to an array of sufficient size
char *format_commas(char *out, int n, int min_digits) {
int len = sprintf(out, "%.*d", min_digits, n);
int i = (*out == '-'), j = len, k = (j - i - 1) / 3;
out[j + k] = '\0';
while (k-- > 0) {
j -= 3;
out[j + k + 3] = out[j + 2];
out[j + k + 2] = out[j + 1];
out[j + k + 1] = out[j + 0];
out[j + k + 0] = ',';
}
return out;
}
The code is easy to adapt for other integer types.
There are many interesting contributions here. Some covered all cases, some did not. I picked four of the contributions to test, found some failure cases during testing and then added a solution of my own.
I tested all methods for both accuracy and speed. Even though the OP only requested a solution for one positive number, I upgraded the contributions that didn't cover all possible numbers (so the code below may be slightly different from the original postings). The cases that weren't covered include: 0, negative numbers and the minimum number (INT_MIN).
I changed the declared type from "int" to "long long" since it's more general and all ints will get promoted to long long. I also standardized the call interface to include the number as well as a buffer to contain the formatted string (like some of the contributions) and returned a pointer to the buffer:
char* funcName(long long number_to_format, char* string_buffer);
Including a buffer parameter is considered by some to be "better" than having the function: 1) contain a static buffer (would not be re-entrant) or 2) allocate space for the buffer (would require caller to de-allocate the memory) or 3) print the result directly to stdout (would not be as generally useful since the output may be targeted for a GUI widget, file, pty, pipe, etc.).
I tried to use the same function names as the original contributions to make it easier to refer back to the originals. Contributed functions were modified as needed to pass the accuracy test so that the speed test would be meaningful. The results are included here in case you would like to test more of the contributed techniques for comparison. All code and test code used to generate the results are shown below.
So, here are the results:
Accuracy Test (test cases: LLONG_MIN, -999, -99, 0, 99, 999, LLONG_MAX):
----------------------------------------------------
print_number:
-9,223,372,036,854,775,808, -999, -99, 0, 99, 999, 9,223,372,036,854,775,807
fmtLocale:
-9,223,372,036,854,775,808, -999, -99, 0, 99, 999, 9,223,372,036,854,775,807
fmtCommas:
-9,223,372,036,854,775,808, -999, -99, 0, 99, 999, 9,223,372,036,854,775,807
format_number:
-9,223,372,036,854,775,808, -999, -99, 0, 99, 999, 9,223,372,036,854,775,807
itoa_commas:
-9,223,372,036,854,775,808, -999, -99, 0, 99, 999, 9,223,372,036,854,775,807
Speed Test: (1 million calls, values reflect average time per call)
----------------------------------------------------
print_number: 0.747 us (microsec) per call
fmtLocale: 0.222 us (microsec) per call
fmtCommas: 0.212 us (microsec) per call
format_number: 0.124 us (microsec) per call
itoa_commas: 0.085 us (microsec) per call
Since all contributed techniques are fast (< 1 microsecond on my laptop), unless you need to format millions of numbers, any of the techniques should be acceptable. It's probably best to choose the technique that is most readable to you.
Here is the code:
#line 2 "comma.c"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <locale.h>
#include <limits.h>
// ----------------------------------------------------------
char* print_number( long long n, char buf[32] ) {
long long order_of_magnitude = (n == 0) ? 1
: (long long)pow( 10, ((long long)floor(log10(fabs(n))) / 3) * 3 ) ;
char *ptr = buf;
sprintf(ptr, "%d", n / order_of_magnitude ) ;
for( n %= order_of_magnitude, order_of_magnitude /= 1000;
order_of_magnitude > 0;
n %= order_of_magnitude, order_of_magnitude /= 1000 )
{
ptr += strlen(ptr);
sprintf(ptr, ",%03d", abs(n / order_of_magnitude) );
}
return buf;
}
// ----------------------------------------------------------
char* fmtLocale(long long i, char buf[32]) {
sprintf(buf, "%'lld", i); // requires setLocale in main
return buf;
}
// ----------------------------------------------------------
char* fmtCommas(long long num, char dst[32]) {
char src[27];
char *p_src = src;
char *p_dst = dst;
const char separator = ',';
int num_len, commas;
num_len = sprintf(src, "%lld", num);
if (*p_src == '-') {
*p_dst++ = *p_src++;
num_len--;
}
for (commas = 2 - num_len % 3;
*p_src;
commas = (commas + 1) % 3)
{
*p_dst++ = *p_src++;
if (commas == 1) {
*p_dst++ = separator;
}
}
*--p_dst = '\0';
return dst;
}
// ----------------------------------------------------------
char* format_number(long long n, char out[32]) {
int digit;
int out_index = 0;
long long i = (n < 0) ? -n : n;
if (i == LLONG_MIN) i = LLONG_MAX; // handle MIN, offset by 1
if (i == 0) { out[out_index++] = '0'; } // handle 0
for ( ; i != 0; i /= 10) {
digit = i % 10;
if ((out_index + 1) % 4 == 0) {
out[out_index++] = ',';
}
out[out_index++] = digit + '0';
}
if (n == LLONG_MIN) { out[0]++; } // correct for offset
if (n < 0) { out[out_index++] = '-'; }
out[out_index] = '\0';
// then you reverse the out string
for (int i=0, j = strlen(out) - 1; i<=j; ++i, --j) {
char tmp = out[i];
out[i] = out[j];
out[j] = tmp;
}
return out;
}
// ----------------------------------------------------------
char* itoa_commas(long long i, char buf[32]) {
char* p = buf + 31;
*p = '\0'; // terminate string
if (i == 0) { *(--p) = '0'; return p; } // handle 0
long long n = (i < 0) ? -i : i;
if (n == LLONG_MIN) n = LLONG_MAX; // handle MIN, offset by 1
for (int j=0; 1; ++j) {
*--p = '0' + n % 10; // insert digit
if ((n /= 10) <= 0) break;
if (j % 3 == 2) *--p = ','; // insert a comma
}
if (i == LLONG_MIN) { p[24]++; } // correct for offset
if (i < 0) { *--p = '-'; }
return p;
}
// ----------------------------------------------------------
// Test Accuracy
// ----------------------------------------------------------
void test_accuracy(char* name, char* (*func)(long long n, char* buf)) {
char sbuf[32]; // string buffer
long long nbuf[] = { LLONG_MIN, -999, -99, 0, 99, 999, LLONG_MAX };
printf("%s:\n", name);
printf(" %s", func(nbuf[0], sbuf));
for (int i=1; i < sizeof(nbuf) / sizeof(long long int); ++i) {
printf(", %s", func(nbuf[i], sbuf));
}
printf("\n");
}
// ----------------------------------------------------------
// Test Speed
// ----------------------------------------------------------
void test_speed(char* name, char* (*func)(long long n, char* buf)) {
int cycleCount = 1000000;
//int cycleCount = 1;
clock_t start;
double elapsed;
char sbuf[32]; // string buffer
start = clock();
for (int i=0; i < cycleCount; ++i) {
char* s = func(LLONG_MAX, sbuf);
}
elapsed = (double)(clock() - start) / (CLOCKS_PER_SEC / 1000000.0);
printf("%14s: %7.3f us (microsec) per call\n", name, elapsed / cycleCount);
}
// ----------------------------------------------------------
int main(int argc, char* argv[]){
setlocale(LC_ALL, "");
printf("\nAccuracy Test: (LLONG_MIN, -999, 0, 99, LLONG_MAX)\n");
printf("----------------------------------------------------\n");
test_accuracy("print_number", print_number);
test_accuracy("fmtLocale", fmtLocale);
test_accuracy("fmtCommas", fmtCommas);
test_accuracy("format_number", format_number);
test_accuracy("itoa_commas", itoa_commas);
printf("\nSpeed Test: 1 million calls\n\n");
printf("----------------------------------------------------\n");
test_speed("print_number", print_number);
test_speed("fmtLocale", fmtLocale);
test_speed("fmtCommas", fmtCommas);
test_speed("format_number", format_number);
test_speed("itoa_commas", itoa_commas);
return 0;
}
Can be done pretty easily...
//Make sure output buffer is big enough and that input is a valid null terminated string
void pretty_number(const char* input, char * output)
{
int iInputLen = strlen(input);
int iOutputBufferPos = 0;
for(int i = 0; i < iInputLen; i++)
{
if((iInputLen-i) % 3 == 0 && i != 0)
{
output[iOutputBufferPos++] = ',';
}
output[iOutputBufferPos++] = input[i];
}
output[iOutputBufferPos] = '\0';
}
Example call:
char szBuffer[512];
pretty_number("1234567", szBuffer);
//strcmp(szBuffer, "1,234,567") == 0
void printfcomma ( long long unsigned int n)
{
char nstring[100];
int m;
int ptr;
int i,j;
sprintf(nstring,"%llu",n);
m=strlen(nstring);
ptr=m%3;
if (ptr)
{ for (i=0;i<ptr;i++) // print first digits before comma
printf("%c", nstring[i]);
printf(",");
}
j=0;
for (i=ptr;i<m;i++) // print the rest inserting commas
{
printf("%c",nstring[i]);
j++;
if (j%3==0)
if(i<(m-1)) printf(",");
}
}
// separate thousands
int digit;
int idx = 0;
static char buffer[32];
char* p = &buffer[32];
*--p = '\0';
for (int i = fCounter; i != 0; i /= 10)
{
digit = i % 10;
if ((p - buffer) % 4 == 0)
*--p = ' ';
*--p = digit + '0';
}

Converting an integer to binary in C

I'm trying to convert an integer 10 into the binary number 1010.
This code attempts it, but I get a segfault on the strcat():
int int_to_bin(int k)
{
char *bin;
bin = (char *)malloc(sizeof(char));
while(k>0) {
strcat(bin, k%2);
k = k/2;
bin = (char *)realloc(bin, sizeof(char) * (sizeof(bin)+1));
}
bin[sizeof(bin)-1] = '\0';
return atoi(bin);
}
How do I convert an integer to binary in C?
If you want to transform a number into another number (not number to string of characters), and you can do with a small range (0 to 1023 for implementations with 32-bit integers), you don't need to add char* to the solution
unsigned int_to_int(unsigned k) {
if (k == 0) return 0;
if (k == 1) return 1; /* optional */
return (k % 2) + 10 * int_to_int(k / 2);
}
HalosGhost suggested to compact the code into a single line
unsigned int int_to_int(unsigned int k) {
return (k == 0 || k == 1 ? k : ((k % 2) + 10 * int_to_int(k / 2)));
}
You need to initialise bin, e.g.
bin = malloc(1);
bin[0] = '\0';
or use calloc:
bin = calloc(1, 1);
You also have a bug here:
bin = (char *)realloc(bin, sizeof(char) * (sizeof(bin)+1));
this needs to be:
bin = (char *)realloc(bin, sizeof(char) * (strlen(bin)+1));
(i.e. use strlen, not sizeof).
And you should increase the size before calling strcat.
And you're not freeing bin, so you have a memory leak.
And you need to convert 0, 1 to '0', '1'.
And you can't strcat a char to a string.
So apart from that, it's close, but the code should probably be more like this (warning, untested !):
int int_to_bin(int k)
{
char *bin;
int tmp;
bin = calloc(1, 1);
while (k > 0)
{
bin = realloc(bin, strlen(bin) + 2);
bin[strlen(bin) - 1] = (k % 2) + '0';
bin[strlen(bin)] = '\0';
k = k / 2;
}
tmp = atoi(bin);
free(bin);
return tmp;
}
Just use itoa to convert to a string, then use atoi to convert back to decimal.
unsigned int_to_int(unsigned int k) {
char buffer[65]; /* any number higher than sizeof(unsigned int)*bits_per_byte(8) */
return atoi( itoa(k, buffer, 2) );
}
The working solution for Integer number to binary conversion is below.
int main()
{
int num=241; //Assuming 16 bit integer
for(int i=15; i>=0; i--) cout<<((num >> i) & 1);
cout<<endl;
for(int i=0; i<16; i++) cout<<((num >> i) & 1);
cout<<endl;
return 0;
}
You can capture the cout<< part based on your own requirement.
Well, I had the same trouble ... so I found this thread
I think the answer from user:"pmg" does not work always.
unsigned int int_to_int(unsigned int k) {
return (k == 0 || k == 1 ? k : ((k % 2) + 10 * int_to_int(k / 2)));
}
Reason: the binary representation is stored as an integer. That is quite limited.
Imagine converting a decimal to binary:
dec 255 -> hex 0xFF -> bin 0b1111_1111
dec 1023 -> hex 0x3FF -> bin 0b11_1111_1111
and you have to store this binary representation as it were a decimal number.
I think the solution from Andy Finkenstadt is the closest to what you need
unsigned int_to_int(unsigned int k) {
char buffer[65]; // any number higher than sizeof(unsigned int)*bits_per_byte(8)
return itoa( atoi(k, buffer, 2) );
}
but still this does not work for large numbers.
No suprise, since you probably don't really need to convert the string back to decimal. It makes less sense. If you need a binary number usually you need for a text somewhere, so leave it in string format.
simply use itoa()
char buffer[65];
itoa(k, buffer, 2);
You can use function this function to return char* with string representation of the integer:
char* itob(int i) {
static char bits[8] = {'0','0','0','0','0','0','0','0'};
int bits_index = 7;
while ( i > 0 ) {
bits[bits_index--] = (i & 1) + '0';
i = ( i >> 1);
}
return bits;
}
It's not a perfect implementation, but if you test with a simple printf("%s", itob(170)), you'll get 01010101 as I recall 170 was. Add atoi(itob(170)) and you'll get the integer but it's definitely not 170 in integer value.
You could use this function to get array of bits from integer.
int* num_to_bit(int a, int *len){
int arrayLen=0,i=1;
while (i<a){
arrayLen++;
i*=2;
}
*len=arrayLen;
int *bits;
bits=(int*)malloc(arrayLen*sizeof(int));
arrayLen--;
while(a>0){
bits[arrayLen--]=a&1;
a>>=1;
}
return bits;
}
void intToBin(int digit) {
int b;
int k = 0;
char *bits;
bits= (char *) malloc(sizeof(char));
printf("intToBin\n");
while (digit) {
b = digit % 2;
digit = digit / 2;
bits[k] = b;
k++;
printf("%d", b);
}
printf("\n");
for (int i = k - 1; i >= 0; i--) {
printf("%d", bits[i]);
}
}
You can convert decimal to bin, hexa to decimal, hexa to bin, vice-versa etc by following this example.
CONVERTING DECIMAL TO BIN
int convert_to_bin(int number){
int binary = 0, counter = 0;
while(number > 0){
int remainder = number % 2;
number /= 2;
binary += pow(10, counter) * remainder;
counter++;
}
}
Then you can print binary equivalent like this:
printf("08%d", convert_to_bin(13)); //shows leading zeros
Result in string
The following function converts an integer to binary in a string (n is the number of bits):
// Convert an integer to binary (in a string)
void int2bin(unsigned integer, char* binary, int n=8)
{
for (int i=0;i<n;i++)
binary[i] = (integer & (int)1<<(n-i-1)) ? '1' : '0';
binary[n]='\0';
}
Test online on repl.it.
Source : AnsWiki.
Result in string with memory allocation
The following function converts an integer to binary in a string and allocate memory for the string (n is the number of bits):
// Convert an integer to binary (in a string)
char* int2bin(unsigned integer, int n=8)
{
char* binary = (char*)malloc(n+1);
for (int i=0;i<n;i++)
binary[i] = (integer & (int)1<<(n-i-1)) ? '1' : '0';
binary[n]='\0';
return binary;
}
This option allows you to write something like printf ("%s", int2bin(78)); but be careful, memory allocated for the string must be free later.
Test online on repl.it.
Source : AnsWiki.
Result in unsigned int
The following function converts an integer to binary in another integer (8 bits maximum):
// Convert an integer to binary (in an unsigned)
unsigned int int_to_int(unsigned int k) {
return (k == 0 || k == 1 ? k : ((k % 2) + 10 * int_to_int(k / 2)));
}
Test online on repl.it
Display result
The following function displays the binary conversion
// Convert an integer to binary and display the result
void int2bin(unsigned integer, int n=8)
{
for (int i=0;i<n;i++)
putchar ( (integer & (int)1<<(n-i-1)) ? '1' : '0' );
}
Test online on repl.it.
Source : AnsWiki.
You can add the functions to the standard library and use it whenever you need.
Here is the code in C++
#include <stdio.h>
int power(int x, int y) //calculates x^y.
{
int product = 1;
for (int i = 0; i < y; i++)
{
product = product * x;
}
return (product);
}
int gpow_bin(int a) //highest power of 2 less/equal to than number itself.
{
int i, z, t;
for (i = 0;; i++)
{
t = power(2, i);
z = a / t;
if (z == 0)
{
break;
}
}
return (i - 1);
}
void bin_write(int x)
{
//printf("%d", 1);
int current_power = gpow_bin(x);
int left = x - power(2, current_power);
int lower_power = gpow_bin(left);
for (int i = 1; i < current_power - lower_power; i++)
{
printf("0");
}
if (left != 0)
{
printf("%d", 1);
bin_write(left);
}
}
void main()
{
//printf("%d", gpow_bin(67));
int user_input;
printf("Give the input:: ");
scanf("%d", &user_input);
printf("%d", 1);
bin_write(user_input);
}
#define BIT_WIDTH 32
char *IntToBin(unsigned n, char *buffer) {
char *ptr = buffer + BIT_WIDTH;
do {
*(--ptr) = (n & 1) + '0';
n >>= 1;
} while(n);
return ptr;
}
#define TEST 1
#if TEST
#include <stdio.h>
int main() {
int n;
char buff[BIT_WIDTH + 1];
buff[BIT_WIDTH] = '\0';
while(scanf("%d", &n) == 1)
puts(IntToBin(n, buff));
return 0;
}
#endif
short a;
short b;
short c;
short d;
short e;
short f;
short g;
short h;
int i;
char j[256];
printf("BINARY CONVERTER\n\n\n");
//uses <stdlib.h>
while(1)
{
a=0;
b=0;
c=0;
d=0;
e=0;
f=0;
g=0;
h=0;
i=0;
gets(j);
i=atoi(j);
if(i>255){
printf("int i must not pass the value 255.\n");
i=0;
}
if(i>=128){
a=1;
i=i-128;}
if(i>=64){
b=1;
i=i-64;}
if(i>=32){
c=1;
i=i-32;}
if(i>=16){
d=1;
i=i-16;}
if(i>=8){
e=1;
i=i-8;}
if(i>=4){
f=1;
i=i-4;}
if(i>=2){
g=1;
i=i-2;}
if(i>=1){
h=1;
i=i-1;}
printf("\n%d%d%d%d%d%d%d%d\n\n",a,b,c,d,e,f,g,h);
}

Convert binary format string to int, in C

How do I convert a binary string like "010011101" to an int, and how do I convert an int, like 5, to a string "101" in C?
The strtol function in the standard library takes a "base" parameter, which in this case would be 2.
int fromBinary(const char *s) {
return (int) strtol(s, NULL, 2);
}
(first C code I've written in about 8 years :-)
If it is a homework problem they probably want you to implement strtol, you would have a loop something like this:
char* start = &binaryCharArray[0];
int total = 0;
while (*start)
{
total *= 2;
if (*start++ == '1') total += 1;
}
If you wanted to get fancy you could use these in the loop:
total <<= 1;
if (*start++ == '1') total^=1;
I guess it really depends on some questions about your strings/program. If, for example, you knew your number wouldn't be bigger than 255 (IE you were only using 8 bits or 8 0s/1s), you could create a function where you hand it 8 bits from your string, traverse it and add to a sum that you returned everytime you hit a 1. IE if you hit the bit for 2^7 add 128 and the next bit you hit was 2^4 add 16.
This is my quick and dirty idea. I think more and Google for ya while at school. :D
For the 2nd part of the question, i.e. "how do I convert an int, like 5, to a string "101" in C?", try something like:
void
ltostr( unsigned long x, char * s, size_t n )
{
assert( s );
assert( n > 0 );
memset( s, 0, n );
int pos = n - 2;
while( x && (pos >= 0) )
{
s[ pos-- ] = (x & 0x1) ? '1' : '0'; // Check LSb of x
x >>= 1;
}
}
You can use the following coding
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void)
{
int nRC = 0;
int nCurVal = 1;
int sum = 0;
char inputArray[9];
memset(inputArray,0,9);
scanf("%s", inputArray);
// now walk the array:
int nPos = strlen(inputArray)-1;
while(nPos >= 0)
{
if( inputArray[nPos] == '1')
{
sum += nCurVal;
}
--nPos;
nCurVal *= 2;
}
printf( "%s converted to decimal is %d\n", inputArray, sum);
return nRC;
}
Use like this:
char c[20];
int s=23;
itoa(s,c,2);
puts(c);
Output:
10111
To answer the second part of the question.
char* get_binary_string(uint16_t data, unsigned char sixteen_bit)
{
char* ret = NULL;
if(sixteen_bit) ret = (char*)malloc(sizeof(char) * 17);
else ret = (char*)malloc(sizeof(char) * 9);
if(ret == NULL) return NULL;
if(sixteen_bit){
for(int8_t i = 15; i >= 0; i--){
*(ret + i) = (char)((data & 1) + '0');
data >>= 1;
}
*(ret + 16) = '\0';
return ret;
}else{
for(int8_t i = 7; i >= 0; i--){
*(ret + i) = (char)((data & 1) + '0');
data >>= 1;
}
*(ret + 8) = '\0';
return ret;
}
return ret;
}
To answer the first part of your question, here is a neat little function I created to convert Binary char strings to integers.
// Function used to change binary character strings to integers
int binToDec(char binCode[])
{
while (binCode != NULL)
{
int base = strlen(binCode) - 1; // the base of 2 to be multiplied, we start of -1 because we dont account for the last bit here
int sum = 0;
for (int i = 0; i < strlen(binCode) - 1; i++) // we do not account for the last bit of the binary code here....
{
int decimal = 1;
if (binCode[i] == '1')
{
for (int j = 0; j < base; j++) // we want to just multiply the number of true bits (not including the 1)
{
decimal = decimal * 2;
}
base = base - 1; // subtract base by 1 since we are moving down the string by 1
}
else // we encounter a zero
{
base = base - 1; // subtract a base multiple every time we encounter a zero...
continue; // carry on with the code
}
sum += decimal;
// starting from the left (higher power) to the end (lowest power or 1)
}
for (int j = strlen(binCode) - 1; j < strlen(binCode) + 1; j++)
{ // accounting for the endian bit that is always 1
if (binCode[j] == '1')
{
sum += 1; // add 1 to the sum total
}
}
return sum; // return the sum as an int
}
return 0;
}

Resources