Click here to Skip to main content
12,078,370 members (49,866 online)
Rate this:
 
Please Sign up or sign in to vote.
See more: C
Hello everyone..!!
I am a very very new programmer who just started learning C...
I need to make a simple program that converts a decimal number to its equal binary
but i'm facing some difficulties!

Here is my source code:

#include <stdio.h>
#include <stdlib.h>

int main()
 
{
int a, b, c;
printf("Type a decimal number: ");
scanf("%d", &a);
if (a<0)
{
printf("The data is incorrect. \n");
printf("Type an unsigned number to continue. \n");
scanf("%d", &a);
}
b=a%2;
a=a/2;
c=a%2;
a=a/2;
 
printf("The binary number you are looking for is %d%d", c,b);
system("pause");
}

That way I can only convert very small numbers which need only 2 digits to be made... But I want to make this program work for bigger numbers as well...
Do I have to add 100 variables..?? I think that's stupid..
There must be a way to make this procedure repeat till the result is 0...
I must tell you that I know too little about C, so plz don't give me a complex answer, for I won't understand it...

Thank you in advance..!!!
Posted 28-Oct-11 3:43am
MG2011180
Edited 28-Oct-11 3:50am
v2
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

Here is a function which can convert from decimal to any base between 2 and 36.

#include <stdio.h>
#include <Windows.h>

//This function is the same as ConvertFromDecimal, only it is hard coded to look as much like your solution as possible. Hopefully you can see the similarities.
int ConvertToBinary(char *szBuffer, int a) {
	//Simple: Zero is the same in any base, so if the number is 0, return 0. 
	if (nDecimal == 0) {
		strcpy(szBuffer, "0");
		return 1;
	}
	char szAlphabet[] = "01";
	unsigned nChar = 0; //The number of characters in our string so far
	//This loop follows the basic structure of your code, only in a loop.
	do {
		szBuffer[nChar++] = szAlphabet[a % 2]; //Notice the similarity here?
		a /= 2; //Notice the similarity here too?
	} while (a != 0); //Instead of just doing the same thing twice, hard coded, we do it in a loop until our number reaches 0.
	//Now we have our string, but it is backwards, so reverse it
	for (int nReverse = 0; nReverse < nChar / 2; ++nReverse) {
		char tmp = szBuffer[nReverse];
		szBuffer[nReverse] = szBuffer[nChar - nReverse - 1];
		szBuffer[nChar - nReverse - 1] = tmp;
	}
	szBuffer[nChar] = 0;
	return nChar;
}
 
int ConvertFromDecimal(char *szBuffer, int nDecimal, int nBase) {
	//Simple: Zero is the same in any base, so if the number is 0, return 0. 
	if (nDecimal == 0) {
		strcpy(szBuffer, "0");
		return 1;
	}
	//This is the possible characters we can use.
	//The first character is for number 0, 2nd character is for the number 1, ...
	//0 -> 0, 1 -> 1, ... 10 -> A, 11 -> B, ... 35 -> Z
	//This allows us to simply index character 10, for example, and get the character 'A'
	char szAlphabet[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	unsigned nChar = 0; //The number of characters in our string so far
	//This loop follows the basic structure of your code, only in a loop.
	do {
		//Add a character to the end of our string buffer. "nDecimal % nBase" is the same as your "a%2"
		szBuffer[nChar++] = szAlphabet[nDecimal % nBase];
		//And now divide by the base. this is the same as your "a=a/2"
		nDecimal /= nBase; // Calculate new value of decimal
	} while (nDecimal != 0); //Keep going until our number is 0. i.e. nothing left
	//Now we have our string, but it is backwards, so reverse it
	//This swaps the first and last character, then the 2nd and 2nd last character, and so on
	//to swap 2 values, we have to save 1 into a temporary variable, then set that value, then set the other one
	for (int nReverse = 0; nReverse < nChar / 2; ++nReverse) {
		//Save the character at the start
		char tmp = szBuffer[nReverse];
		//Set the character at the start to the character which is the same distance from the end
		szBuffer[nReverse] = szBuffer[nChar - nReverse - 1];
		//Now set the character at the end to the one we saved earlier
		szBuffer[nChar - nReverse - 1] = tmp;
	}
	szBuffer[nChar] = 0; //Terminate the string. strings in C++ end with the NULL terminator character, ASCII 0.
	return nChar; //Return the length of the string. It could be useful for something
}
 
int main() {
	char szBuffer[16]; //This must be big enough to hold the output +1 byte for the terminator
	//Now just run some tests to check it is working. Compared to windows calculator.
	int n = 1;
	ConvertFromDecimal(szBuffer, n, 2);
	printf("%d in binary is %s\n", n, szBuffer);
	n = 5;
	ConvertFromDecimal(szBuffer, n, 2);
	printf("%d in binary is %s\n", n, szBuffer);
	n = 1085;
	ConvertFromDecimal(szBuffer, n, 2);
	printf("%d in binary is %s\n", n, szBuffer);
	n = 1000;
	ConvertFromDecimal(szBuffer, n, 2);
	printf("%d in binary is %s\n", n, szBuffer);
	n = 65536;
	ConvertFromDecimal(szBuffer, n, 2);
	printf("%d in binary is %s\n", n, szBuffer);
	return 0;
}

EDIT:
This code does pretty much what you were doing, only it is in a loop so it works on any size number. Also, in stead of a hard coded base of 2, it takes the base in as a parameter.

EDIT2:
Added more comments to better explain algorithm
  Permalink  
v5
Comments
MG2011 28-Oct-11 9:58am
   
Thanks a lot!!
I read it many times but I really can't figure it out...
Too complex for me!:-(
Andrew Brock 28-Oct-11 10:15am
   
I have added some more comments to better explain it.
Nice to see someone trying to understand the code, rather than just using it.

At the simplest level, it is just your algorithm, but in a do loop. That allows it work on any size number.
MG2011 28-Oct-11 10:44am
   
Thanks for the extra comments! I figured it out and the whole idea is very clever!
The point is that I have to present it to my professor on Monday and if I show him this he will never believe that I did it myself! :-(
Till now we've been coding programmes like "Hello world" and summing a couple of numbers...!
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 2

If you are trying to actually convert a decimal number into it's binary equivilent:
decimal 23 -> binary 10111
There there are a couple of things which make it easier:
1) A loop
2) The Binary AND operation
3) The bitwise shift operators.

The first thing to realize is that you don't want to start with the bottom bit of the entered number - that is the least significant bit, and you want to print that on the right hand side. So, start with the left most bit. Assuming we are only dealing with 8 bit numbers (i.e. decimal 0 to 255 inclusive) you want to print the top most bit as a "1" or a "0"
This is where the Binary AND operator ('&') comes in.
if ((myNumber & 0x80) != 0)
   {
   printf("1");
   }
else
   {
   printf("0");
   }
The next thing you need to do is move the bit you just checked out of the way. That is where the bitwise shift operators ("<<" and ">>") come in handy.
myNumber = myNumber << 1;
Moves the whole number one place to the left - the equivalent of multiplying it by two.
Then all you need to do is set up a loop:
for (i = 0; i < 8; i++)
   {
   ...
   }
This isn't the most efficient way to do it - there are a lot of much better ones - but it does give you the basics. All you have to do is bolt the bits together, and see what happens!



"Thank you very much, I understood this one till a certain point...
What do I write in order to set the loop? I tried a couple of things and althouth I get no error the program writes "0", no matter what number I enter...
And also could you tell me what "myNumber & 0x80" means?Cause i can't understant it..! Frown | :-( "


Sorry! I assumed a few things too many... Laugh | :laugh:

OK: the loop:
for (i = 0; i < 8; i++)
   {
   ...
   }
This sets up a loop, and runs it. A for loop has three parts, separated by ';' characters:
for ( set up code ; continue while still true condition ; do every time you get to the end of the loop code )
So the code above sets an integer called i (which you have to declare at the top of your method) to the value zero
i = 0
And then runs around the loop adding one to i each time:
i++
While i is still less than eight
i < 8
So, it goes round the loop a total of eight times, once for each bit in the eight bit number you are working with. Try it! Paste the code into your program, and add the line
printf("%d\n", i);
in between the curly brackets.

The other bit isn't too complex either:
myNumber & 0x80
myNumber is a variable, which holds the number you want to convert to binary. '&' is the Binary AND operator, and 0x80 is a way of writing numbers which are not in base ten: the "0x" bit tells the compiler that what follows is a number in base 16, or Hex. Why do we use hex instead of decimal or binary? Because binary gets very long, very quickly, and decimal is difficult to mentally convert to what the machine is doing. It's a lot easier to work with hex when numbers get big and you need a sense for how big exactly. Wiki should have some good stuff on number bases, but for the moment just accept that it is easier to "see" which bits are set in hex than it is in decimal. Laugh | :laugh:

In this case, 0x80 is the hex equivalent of 128 in decimal, or 10000000 in binary. What it actually is in a number with just the top bit out of the eight set to one. When you use the binary AND operation, it combines the two numbers together, looking at each bit individually. If the same bit is set (or equal to 1) in both numbers, then it is set to 1 in the output. In all other cases it is set to 0.
So a binary AND of 0x80 and any number will be zero if the eighth bit in the number is zero, and non-zero if it is one.

Does that make sense, or is it a bit much to understand - it's a lot easier with pictures!



I wrote this and although the compiler says that there are no errors, as soon as I type a number it stops working...!Frown | :-(

#include
#include

int main()
{
int myNumber, i;
printf("Give number: ");
scanf("%d", myNumber);
if (myNumber & 0x80 != 0)
{
printf("1");
}
else
{
printf("0");
}
myNumber = myNumber << 1;
for (i = 0; i < 8; i++)
{
printf("%d\n", i);
}
system("pause");
}

I'm certain that I've made mistakes, but I can't find them...
Your answer was really very very helpful!!! Smile | :)


First off - indent your code! It makes it a lot easier to see at a glance what is going on:
int main()
{
    int myNumber, i;
    printf("Give number: ");
    scanf("%d", myNumber);
    if ((myNumber & 0x80) != 0)
    {
        printf("1");
    }
    else
    {
        printf("0");
    }
    myNumber = myNumber << 1;
    for (i = 0; i < 8; i++)
    {
        printf("%d\n", i);
    }
    system("pause");
}
What that will do is ask for a number, read it from the user and crash. Big Grin | :-D

Why will it crash? Because you are trying to read the number into the wrong place. You need to give it the address of myNumber rather than the content:
scanf("%d", myNumber);
Becomes
scanf("%d", &myNumber);
(Don't worry too much about what that means - your course will explain it pretty soon)

Then, it will process the top bit of the eight, before printing out the loop count each time it goes round.
Try moving the if-else stuff inside the loop:

int main()
{
    int myNumber = 0, i;
    printf("Give number: ");
    scanf("%d", &myNumber);
    for (i = 0; i < 8; i++)
    {
        if ((myNumber & 0x80) != 0)
        {
            printf("1");
        }
        else
        {
            printf("0");
        }
        myNumber = myNumber << 1;
    }
    system("pause");
}
(See what I mean about indenting?)

[edit]Added brackets to if condition to handle precedence rules Blush | :O - OriginalGriff[/edit]
[edit]Changed "Right" to "Left". Bitwise shift operator << moves to the Left, not the Right Blush | :O - OriginalGriff[/edit]
  Permalink  
v5
Comments
MG2011 28-Oct-11 9:57am
   
Thank you very much, I understood this one till a certain point...
What do I write in order to set the loop? I tried a couple of things and althouth I get no error the program writes "0", no matter what number I enter...
And also could you tell me what "myNumber & 0x80" means?Cause i can't understant it..! :-(
OriginalGriff 28-Oct-11 10:19am
   
Answer updated
enhzflep 28-Oct-11 10:23am
   
Great response. my +5
MG2011 28-Oct-11 10:41am
   
I wrote this and although the compiler says that there are no errors, as soon as I type a number it stops working...!:-(

#include
#include

int main()
{
int myNumber, i;
printf("Give number: ");
scanf("%d", myNumber);
if (myNumber & 0x80 != 0)
{
printf("1");
}
else
{
printf("0");
}
myNumber = myNumber << 1;
for (i = 0; i < 8; i++)
{
printf("%d\n", i);
}
system("pause");
}

I'm certain that I've made mistakes, but I can't find them...
Your answer was really very very helpful!!! :-)
OriginalGriff 28-Oct-11 12:23pm
   
Answer updated
MG2011 28-Oct-11 12:45pm
   
I wrote that one and now the program runs but when I type for example 6 it says 000000000, and in general it doesn't make a right conversion!:-(
Why does it happen?
I found a program which uses this:

for(i=0; myNumber!=0; i++)
{
bin[i]=myNumber%2;
myNumber=myNumber/2;
}
for(j=i-1; j>=0; j--)
{
printf("%d", bin[j]);
}

and it works but I don't know what that bin[i] thing is and of course i can't show that to my professor!! :-(
OriginalGriff 28-Oct-11 14:11pm
   
Oops! That's entirely my fault: I forgot the operator precedence rules :blush:
Change the if line by adding a pair of brackets:

if (myNumber & 0x80 != 0)
becomes:
if ((myNumber & 0x80) != 0)

I'm too used to C# which would have complained because the result was not a boolean value... (Don't worry too much about that either! :laugh:)
OriginalGriff 28-Oct-11 14:16pm
   
Now that's fixed: "the bin[i] thing" is an array - a way to create lots of variables without giving them all names - ignore it for the moment, your tutor will explain that very soon! Right at the moment you have enough to understand without adding more complexity.
MG2011 28-Oct-11 17:19pm
   
I figured it out!! I wrote i<10 and instead of 128-->512 and now I can also calculate numbers with 10 digits!:-)
OriginalGriff 29-Oct-11 3:56am
   
Well done! (it'll actually go to either 16 or 32 depending on your compiler and the size of an int)
MG2011 29-Oct-11 4:58am
   
I wrote i<31 and it works for huge numbers as well!
I need to ask you one more thing!
Above you write about "<<":
"Moves the whole number one place to the right"
I thought that this symbol moved it to the left..!
OriginalGriff 29-Oct-11 5:22am
   
Oops! I must get round to painting "L" and "R" on my shoes... :blush:
MG2011 29-Oct-11 5:32am
   
No big deal! (-: One last thing! I read last night that "<<" moves all the bits of my number by 1 place(in this occasion)! But still, when I press 6 which is 110 in binary it doesn't add an extra 0 after that...! That's the only step that I haven't fully understood!(You must be really patient, after all these questions I asked! :blush: )
OriginalGriff 29-Oct-11 5:41am
   
The patience isn't a problem - it's nice to find someone who wants to learn rather than just get their homework done for them! :laugh:
Because it moves the number without changing the number of times you go round the loop.
If the number in the for statement doesn't match the number in the if statement (i < 8 makes it go round eight times, 0x80 is just the eight bit) then it would add zeros after the actual number.
Try it! Save your code somewhere safe so it won't be destroyed if you do mess things up, and play around.
Learn to use whatever debugger you have as well - it really helps you to understand what is happening.
What are you using for edit / compile / run?
MG2011 29-Oct-11 5:50am
   
Oh I got it, so it is makes 6 look like 00000110, right?
I'm using DevC++ from bloodshed.com and it is fine for the small programmes that I've made so far...! It has a button that says debug, so it must be a debugger as well...!
OriginalGriff 29-Oct-11 6:03am
   
If you are using a fairly modern PC, it might be worth your having a look at Visual Studio - as a student you may get the full version free / cheap but there is always the Express version which is always free from Microsoft and misses out not a lot - it has a full debugger integrated into the editor along with a lot of other nice bits. Plus it makes it easier to go on to C++ Windows and C++ .NET, C# and so forth. But if you have to use DevC++ for your course then it is probably best to stick with it - I've never used it so I can't comment (the web page is a bit... primitive...and the "requires Windows 95 or higher" puts me off a little!)
MG2011 29-Oct-11 6:08am
   
Yesterday I downloaded Visual Studio 2011, it is free for students! But my professor says that using visual studio for these programmes is like killing an ant with a nuclear bomb!lol
OriginalGriff 29-Oct-11 6:19am
   
:laugh:
He's right, it is!
But having said that, if VS is what you are going to be using later, then it may make some sense to learn how to use it from the beginning instead of having to change horses in midstream.

But do bear in mind that VS2011 is a Developer Preview. That means it is a long way from complete and may well change considerably between now and release. This means that MS do not guarantee that any software you develop on VS2011 will work on (or even be able to load into) the release version.
MG2011 29-Oct-11 9:08am
   
So do you think that I should download VS2010? Is that one a preview too?
You are right about it, I should get used to it now because next year we'll be using it at the university!
Thank you so much for your answer and your help! I think that I learned many important things that I will use from this day on..! :-)
OriginalGriff 29-Oct-11 9:33am
   
I would - the express edition at least.

I wish you good luck - I think you will do well with that attitude. Let us know how you do...
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 3

This basic assignment is to teach you how to write your own "Format / printf" routines, a skill that will come in handy in other assignments as some basic looping and/or recursion are used in this solution.

Back when I had to do this ("C" didn't exist then Smile | :) we used recursion instead of loops since you determine each digit from right to left but want to print it from left to right. Recursion helps you do that.

#include "stdafx.h"
#include "stdlib.h"
 
char *ToChar = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
void print_radix(char **b, int v, int r)
{
    int d = v % r;
    v = v / r;
    if (v != 0)
        print_radix(b, v, r);
    *(*b) = ToChar[d];
    *b += 1;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    char buf[128];
    char *p;
    int n;
 
    n = 2;
    p = buf;
    print_radix(&p, n, 2);
    *p = '\0';
    printf("%d in binary is %s\n", n, buf);
 
    n = 8;
    p = buf;
    print_radix(&p, n, 2);
    *p = '\0';
    printf("%d in binary is %s\n", n, buf);
 
    n = 257;
    p = buf;
    print_radix(&p, n, 2);
    *p = '\0';
    printf("%d in binary is %s\n", n, buf);
 
    n = 65535;
    p = buf;
    print_radix(&p, n, 2);
    *p = '\0';
    printf("%d in binary is %s\n", n, buf);
 
    return 0;
}
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Mobile
Web01 | 2.8.160212.1 | Last Updated 29 Oct 2011
Copyright © CodeProject, 1999-2016
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100