Click here to Skip to main content
15,880,651 members
Please Sign up or sign in to vote.
5.00/5 (4 votes)
See more:
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:

C++
#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
Updated 28-Oct-11 2:50am
v2

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

C++
#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
 
Share this answer
 
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...!
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.
C++
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.
C++
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:
C++
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..! :-("


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

OK: the loop:
C++
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
C++
i = 0
And then runs around the loop adding one to i each time:
C++
i++
While i is still less than eight
C++
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
C++
printf("%d\n", i);
in between the curly brackets.

The other bit isn't too complex either:
C++
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:

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...!:-(

#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!!! :-)


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. :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:
C++
scanf("%d", myNumber);
Becomes
C++
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:

C#
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 :o - OriginalGriff[/edit]
[edit]Changed "Right" to "Left". Bitwise shift operator << moves to the Left, not the Right :o - OriginalGriff[/edit]
 
Share this answer
 
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 <stdio.h>
#include <stdlib.h>

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
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 :) 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.

C#
#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;
}
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900