A binary to decimal program - c

I was practicing basic programs of C and tried to do a binary to decimal conversion.
Below is the code I tried but it did not produce correct results. I couldn't understand where my logic goes wrong.
/* binary to decimal */
#include<stdio.h>
int main()
{
int a,i,p,sum=0;
printf("enter binary number\n");
scanf("%u",&a);
for(i = 0 ; i < 5; i++) /* Taking only 5 digits in binary */
{
if((a & 1<<i))
{
p = 1<<i;
sum = sum +p;
}
}
printf("%d\n",sum);
return 0;
}
I entered 1001 and was expecting 9 to be the output, but output was 1001?

scanf("%u",&a); will read a decimal number. Therefore when you enter 1001 it will be 0011 1110 1001 in binary and after you convert this number back to decimal it becomes 100110. You should read it as a string to preserve the binary form
And then the code you wrote only checks the lower 5 bits of the input value. If you enter 1001 it will output 9 as "expected" because the lower bits of 1001 is 01001 which is accidentally the same for 9. The output is not 1001 as you described. That means the code above is not the original code you ran. If you enter another number the result will be different. For example entering 36 will print 4 on the output

Reason is very simple, variable 'a' is of type int hence when you provide the input as 1001 it becomes a integer of 1001 not a binary for the compiler, so you will not get the proper result, don't use shift operator, try some thing similar as suggested by others

This should help you:
#include<stdio.h>
int main()
{
int a,i,p,sum=0;
int temp;
printf("enter binary number\n");
scanf("%d",&a);
for(i = 0 ; i<5; i++) /* Taking only 5 digits in binary */
{
temp=a % 10;
a = a/10;
p = temp<<i;
sum = sum +p;
}
printf("%d\n",sum);
return 0;
}

You would do better to take the input as a string, and starting from the end of that string add the place values for the 1 digits.
%u interprets a decimal string as an integer, you are then trying to interpret the decimal representation of the resultant integer value as binary. Not only is that confusing and somewhat irrational, it will limit you to 10 binary digits.
Consider this:
/* binary to integer */
#include <stdio.h>
#include <string.h>
int main()
{
int pv = 1 ;
int value = 0 ;
char bin[33] ;
printf("Enter binary number: ");
scanf("%32s", bin ) ;
for( int i = strlen( bin ) - 1; i >= 0; i-- )
{
if( bin[i] == '1' )
{
value += pv ;
}
pv *= 2 ;
}
printf( "%d\n", value ) ;
return 0 ;
}
Note also that what is happening here is not a conversion to decimal, but rather conversion to integer. All values are stored internally in binary, it is only decimal if you choose to output a decimal string representation of the integer value.
A potentially more efficient version of the above that exploits the internal binary representation of integers is:
/* binary to integer */
#include <stdio.h>
#include <string.h>
int main()
{
int pv = 1 ;
int value = 0 ;
char bin[33] ;
printf("Enter binary number: ");
scanf("%32s", bin ) ;
for( int i = strlen( bin ) - 1; i >= 0; i-- )
{
if( bin[i] == '1' )
{
value |= pv ;
}
pv <<= 1 ; ;
}
printf( "%d\n", value ) ;
return 0 ;
}

These lines are wrong (I think..):
p = 1<<i;
sum = sum +p;
In order to comput the decimal value you have to do this:
p= pow(2,i);
sum = sum+p;
You need to raise 2 to the power i.
See this link for a good example code:
http://www.daniweb.com/software-development/c/threads/307756/binary-to-decimal-conversion-in-c

This code can be used in C++:
string str = "1001";
int temp = 0;
for(int c=0;c<str.length();c++){
int v = atoi( str.substr(c,1).c_str() );
temp=temp+(v*(pow (2, str.length()-c-1)));
}
cout << temp;

Related

why this code isn't converting decimals to binary from decimals 0 to 31

So I was trying to convert a decimal number to binary using c. In this code every thing seems to be working well. Also this code does work for decimals from 32, 33 and go on. But this code doesn't work for decimals from 0 to 31. What's the bug in here.
#include <stdio.h>
#include <math.h>
int main(void)
{
int decimal;
printf("Enter the decimal value: ");
scanf("%i", &decimal);
int n, remainder;
int i, j, k;
for (int i = 0; i < decimal; i++)
{
if (pow(2, i) <= decimal)
{
n = i;
}
}
char index[n];
int quotient[n];
quotient[0] = decimal;
for (i = 0; i <= n; i++)
{
quotient[i + 1] = quotient[i] / 2;
remainder = quotient[i] % 2;
if (remainder == 1)
{
index[i] = '1';
}
else
{
index[i] = '0';
}
}
for (int k = n; k >= 0; k--)
{
printf("%c", index[k]);
}
return 0;
}
The number returned by scanf() is a bit pattern (binary) representation of the base10 value you enter.
You've got the right idea (trying to 'pick apart' those bits), but the method used is dubious and confusing.
Below is a loop of some familiar values being converted to strings of 1's and 0's.
Consider what it is doing at each step...
int main() {
for( int i = 253; i <= 258; i++ ) {
printf( "Decimal %d: ", i );
unsigned int bitmask = 0;
bitmask = ~bitmask;
bitmask &= ~(bitmask >> 1); // High bitmask ready
// skip over leading 0's (optional)
while( bitmask && (bitmask & i) == 0 ) bitmask >>= 1;
// loop using bitmask to output 1/0, then shift mask
do {
putchar( (bitmask & i) ? '1' : '0' );
} while( (bitmask >>= 1) != 0 );
putchar( '\n' );
}
return 0;
}
Output:
Decimal 253: 11111101
Decimal 254: 11111110
Decimal 255: 11111111
Decimal 256: 100000000
Decimal 257: 100000001
Decimal 258: 100000010
I don't like this, but you seem to want to use pow() to find the highest set bit in the incoming integer. Perhaps this will lead you to the solution you are looking for.
int main() {
int n = 0;
// generate a series of numbers as input
for( int decimal = 1; decimal < 1000*1000*1000; decimal = decimal * 2 + 1 ) {
// Limited of 32 bit integers INCLUDING sign bit
for (int i = 0; i < 31; i++) {
int guess = (int)pow( 2, i ); // make a guess with this value
printf( "Guess %d\n", guess );
if( guess > decimal ) { // guess now encompasses set bits
n = i; // Found what is needed.
break;
}
}
printf( "decimal input = %d: examining %d bits\n", decimal, n );
getchar();
}
return 0;
}
Here's one sample of the output of the above.
Guess 1
Guess 2
Guess 4
Guess 8
Guess 16
Guess 32
Guess 64
decimal input = 63: examining 6 bits
Note: this sort of thing will only work for positive values. It'll probably blow up if you want the bit pattern of a negative integer.
And, because you want to store an array of quotient, you need to dimension it to have +1 elements to avoid stepping out of bounds as you peel-off each bit through division...

C: Decimal Value

Can any one help me sort out one problem, i have to reverse a number without using array(int/char) for storing them.
input1 = 123
output1 = 321
input2 = 2300
output2 = 0032
I am trying to find the solution but 0 got erased while printing so i thought of octal conversion but still no solution, so i went with the decimal places and i made the 23 to 0.0032. Now my problem is how can i extract the 0032 from that part.
Is there any possible way to achieve this without using array(int/char), with that it will be easy.
#include<stdio.h>
#include<math.h>
int main()
{
int number =3200;
int temp;
while (number >0)
{
temp= number%10;
printf("%d",temp);
number = number/10;
}
return 0;
}
you could use recursion to solve this problem, without using any array in fact u could also reverse a string without using any array using recursion. This code works for both numbers and strings and it has no arrays:
char reverse(int a)
{
char c,d;
if(a=='\n')
return 0;
c=getchar();
d=reverse(c);
putchar(a);
return (c);
}
int main()
{
char c;
scanf("%c",&c);
reverse(c);
}
for a start try this.
int n, l;
char nBuf[126];
n = 1230010;
l = sprintf(nBuf, "%d", n );
while( l >= 0 )
printf("%c", nBuf[l--] );
Though if you are taking input from stdin take it as string rathar than as int or long.
Edit - for not using array
int n = 123;
while(n) {
printf("%d", n%10);
n/=10;
}
I am assuming to get a value of this sort "output2 = 0032" it is better of being a string, else formatting complications turns up with input value length and format left space with zeros etc etc.
This becomes fairly easy if you know that you can represent numbers like so:
x = a_0 + a_1 * b^1 + a_2 * b^2 + ...
a_i are the digits
b is the base
To extract the lowest digit, you can use the remainder: x % b
Dividing by the base "removes" the last digit. That way you can get the digits in order lowest to highest.
If you reverse the digits then the lowest becomes the highest. Looking at below transformation it's easy to see how to incrementally build up a number when the digits come in order highest to lowest:
x = a_0 + b * (a_1 + b * (a_2 + ...
You start of with 0, and for each digit you multiply with the base and then add the digit.
In pseudo code:
output = 0
while input != 0
digit = input % base
input = input / base ;; integer division
output = output * base + digit
end
If you want to store leading zeros, then you need to either store the digits in an array, or remember for how many steps of above loop the output remained zero:
output = 0
zeros = 0
while input != 0
digit = input % base
input = input / base ;; integer division
output = output * base + digit
if output == 0
zeros = zeros + 1
end
end
To print that you obviously need to print zeros zeros and then the number.
Live example here, relevant code:
unsigned reverse(
unsigned input,
unsigned const base,
unsigned * const zeros) {
unsigned output = 0;
unsigned still_zero = 0;
for (; input != 0; input/=base) {
output *= base;
output += input % base;
if (output == 0) {
++still_zero;
}
}
if (zeros != NULL) {
*zeros = still_zero;
}
return output;
}
void print_zeros(unsigned zeros) {
for (; zeros != 0; --zeros) {
printf("0");
}
}
Recursion allows for a simple solution. A small variation on #vishu rathore
void rev_dec(void) {
int ch = getchar();
if (isdigit(ch)) {
rev_dec();
}
if (ch >= 0) putchar(ch);
}
int main(void) {
rev_dec();
return 0;
}
input
0123456789012345678901234567890123456789
output
9876543210987654321098765432109876543210

Converting a negative decimal to binary

So, I made this code.
Basically, takes in the number, then if negative, converts it to positive, calculates its binary and then its one complement and then adds 1.
#include <stdio.h>
int main (void)
{
int bin[8]={0};
int sum[8];
int orig,num,i=0,j;
int addn[8] = {0,0,0,0,0,0,0,1};
int carry = 0;
printf("Please enter the number\n");
scanf("%d",&num);
if ( num < 0 )
{
orig = num;
num = -num;
}
while (num!= 0)
{
bin[8-i-1] = num%2;
num = num/2;
i++;
}
for ( j = 0; j < 8; j++ )
{
printf("%d",bin[j]);
}
printf("\n");
if ( orig < 0 )
{
for ( i = 0; i < 8; i++ )
{
if (bin[i] == 0)
bin[i] = 1;
else
bin[i] = 0;
}
for ( i = 0; i < 8; i++ )
{
sum[i] = ((bin[i]^addn[i])^carry);
carry = ((bin[i] & addn[i])| (bin[i] & carry) | (addn[i] & carry) );
}
printf("The 2's complement of the number is \n");
printf("%d",carry);
for ( i = 0; i < 8; i++ )
{
printf("%d",sum[i]);
}
printf("\n");
}
return 0;
}
When I enter the value as 4, it correctly displays its binary value. However, it shows the its 2 compliment as 111111010 ( This is with carry ). Why is this happening? The 2's compliment form of -4 should be different.
Also, is there any other method of converting a negative number to its 2's compliment form?
If you check the 1's complement you'll find that's correct.
The slip is, you're storing the MSB in num[0] and the LSB in num[7], so when you're adding, you need to begin at the 7 end, not the 0 end. Putting (8-i-1) in all the addition part, produces something more like :
./a.out
Please enter the number
-4
00000100
The 1's complement of the number is
11111011
The 2's complement of the number is
011111001
That looks almost right at the low end, but the sign bit looks wrong, because you suddenly are outputting 9 bits, may be you intend to show the overflowing carry? I'm a bit confused about your output intentions and I haven't even examined that part of the source carefully.
I won't post the fixed source yet, you should try to learn to debug it yourself by putting in the extra printf's and reasoning about how you input the number initially.
Thanks for the nifty example program, though it could do with some serious refactoring for clarity. Is it a study exercise? If so you really SHOULD learn to find errors yourself.
Here goes with the corrections I intended but didn't quite input correctly first time :)
So to check the 1's complement was correct :
printf("The 1's complement of the number is \n");
for ( j = 0; j < 8; j++ )
{
printf("%d",bin[j]);
}
printf("\n");
Before starting the add. Then to fix :
for ( i = 0; i < 8; i++ )
{
sum[8-i-1] = ((bin[8-i-1]^addn[8-i-1])^carry);
carry = ((bin[8-i-1] & addn[8-i-1])| (bin[8-i-1] & carry) | (addn[8-i-1] & carry) );
}
Originally I had typo ((bin[i-i-1]^addn but I didn't really care about exact results as I knew I had found what was wrong and could explain where the fault lay.

Correct algorithm to convert binary floating point "1101.11" into decimal (13.75)?

I have written a program in C to convert a floating point number represented in binary (1101.11) into a decimal (13.75).
However, I cannot seem to get the correct value out of the algorithm.
What is the correct method for converting a binary floating point number into a decimal?
I am using Dev CPP compiler (32 bit). The algorithm is defined below:
void b2d(double p, double q )
{
double rem, dec=0, main, f, i, t=0;
/* integer part operation */
while ( p >= 1 )
{
rem = (int)fmod(p, 10);
p = (int)(p / 10);
dec = dec + rem * pow(2, t);
t++;
}
/* fractional part operation */
t = 1; //assigning '1' to use 't' in new operation
while( q > 0 )
{
main = q * 10;
q = modf(main, &i); //extration of frational part(q) and integer part(i)
dec = dec+i*pow(2, -t);
t++;
}
printf("\nthe decimal value=%lf\n",dec); //prints the final output
}
int main()
{
double bin, a, f;
printf("Enter binary number to convert:\n");
scanf("%lf",&bin);
/* separation of integer part and decimal part */
a = (int)bin;
f = bin - a;
b2d(a, f); // function calling for conversion
getch();
return 0;
}
You are not, as you believe, reading "1101.11" as a floating point number represented in binary. You are reading it as a base-10 floating point number converted into an IEEE double-precision floating-point value, and then trying to change the base.
The inherent imprecision of this intermediate step is the reason for your problem.
A better approach, as suggested by Vicky, is to:
read "1101.11" as a string or line of text
convert the whole and fractional parts (whole=b1101=13 and numerator=b11=3, denominator=4)
re-combine these into whole + numerator/denominator = 13.75
Solution
The following will work as expected:
Output:
➤ gcc bin2dec.c -lm -o bin2dec && bin2dec
1101.11 -> 13.750000
1101 -> 13.000000
1101. -> 13.000000
.11 -> 0.750000
Code (bin2dec.c):
#include <stdio.h>
#include <math.h>
double convert(const char binary[]){
int bi,i;
int len = 0;
int dot = -1;
double result = 0;
for(bi = 0; binary[bi] != '\0'; bi++){
if(binary[bi] == '.'){
dot = bi;
}
len++;
}
if(dot == -1)
dot=len;
for(i = dot; i >= 0 ; i--){
if (binary[i] == '1'){
result += (double) pow(2,(dot-i-1));
}
}
for(i=dot; binary[i] != '\0'; i++){
if (binary[i] == '1'){
result += 1.0/(double) pow(2.0,(double)(i-dot));
}
}
return result;
}
int main()
{
char bin[] = "1101.11";
char bin1[] = "1101";
char bin2[] = "1101.";
char bin3[] = ".11";
printf("%s -> %f\n",bin, convert(bin));
printf("%s -> %f\n",bin1, convert(bin1));
printf("%s -> %f\n",bin2, convert(bin2));
printf("%s -> %f\n",bin3, convert(bin3));
return 0;
}
Explanation
The above code works by first finding the index of the decimal point in the number.
Once that is known, it walks the string both backwards and forwards from this index, adding the appropriate value to the result variable.
The first loop walks backwards from the decimal point and accumulates the powers of 2 if the character is 1. It takes the distance from the decimal point as the power of two, minus one for the indexing to be correct. Ie, it accumulates :
pow(2,<distance-from-decimal-point>)
The loop stops when the index reaches the beginning of the string.
The second loop walks forward until the end of the string, and deals with the fractional part as expected it also uses the distance from the index, but this time accumulates fractional parts:
1/pow(2,<distance-from-decimal-point>)
Worked out example:
1101.11 = 1101 + 0.11
1101 = 1*2^3 + 1*2^2 + 0*2^1 + 1*2^0 = 8 + 4 + 0 + 1 = 13
0.11 = 1/(2^1) + 1/(2^2) = 0.5 + 0.25 = 0.75
1101.11 = 13.75
Beware of malformed input. "10gsh.9701072.67812" will give you a result. It won't mean much :)
This piece of code behaves abnormally: I added some simple print statement
while(q>0)
{
double i;
main=q*10.0;
q=modf(main, &i); //extration of frational part(q) and integer part(i)
cout << "main = " << main << " frac part " << q << " int part " << i << endl;
cin.get();
dec=dec+i*pow(2,-t);
t++;
}
When you input 1101.11, the following output shown:
Enter binary number to convert(e.g: 1101.11 which will be 13.75 in decimal):
1101.11
bin in main 1101.11
p 1101 q 0.11
//inside the above while loop code
main = 1.1 frac part 0.1 int part 1
main = 1 frac part 1 int part 0 //^^^^^Error, given main=1, it should output integer part 1, fraction part 0
main = 10 frac part 1 int part 9 //^^^^^same strange error here, it should exit while already
So you got wrong result. I tested modf separately with input 1, it gave correct result.
So my guess is that you are reading the binary number as double, then tries to convert this double to binary back. There might be something going on under the hood for the precision of number though it shows that it is 1101.11. As suggested by #Useless, You may need to read the number as a string, figure out the substring before and after the decimal point . Then convert this two part into decimal separately.

Converting from decimal to binary number system using strings

I need help trying to fix the second part of my program, converting decimal to binary, this is what I have so far and when i compile it i keep getting 0 so im not sure what i did wrong. any help please?
#include <stdio.h>
#include <string.h>
#include <math.h>
int main()
{
char string[100];
int s;
char a;
char j;
int sum = 0;
int r;
int q;
printf("B = B to D\n");
printf("D = D to B\n");
printf("choose which one to convert to:");
scanf("%c%c", &a, &j);
if (a == 'B')
{
printf("enter binary number to convert to decimal: ");
scanf("%s", string);
for(s = strlen(string)-1; s >= 0; s--)
{
if(string[s] == '1')
{
sum = sum + pow(2, strlen(string) - (s +1));
}
}
printf("the decimal number is: %d\n", sum);
}
if (a == 'D')
{
printf("enter decimal number to convert to binary: ");
scanf("%s", string);
while (r > 0)
{
r = q%2;
q = q%2;
}
printf("the binary number is: %d\n", r);
}
return 0;
}
There are a few problems here. For one thing, the first time that you check r, it is uninitialized. Another problem is that you're setting both r and q to the same value every time you go through the while loop. You probably want q = q/2 instead of q = q%2. Finally, you're overwriting r every pass through the loop, instead of building up a string of bits. Here's some pseudocode for what you want to do:
output_string = ""
while input > 0:
output_string = concat(input%2, output_string)
input /= 2
print output_string
Note that you're also never converting the string you read in to an integer and putting that in q, so you'll need to do that as well.
This C99 code will do the trick if you want a negative number to be printed as a string of binary digits with a sign:
if (a == 'D')
{
int r;
printf("enter decimal number to convert to binary: ");
scanf("%d", &r);
int i = 0;
int p = (r >= 0) ? (r = -r, 1) : 0;
string[i++] = '\0';
do
{
string[i++] = (r % 2) == 0 ? '0' : '1';
r /= 2;
} while (r != 0);
if (!p)
string[i++] = '-';
int k = 0;
while (--i > k)
{
char t = string[i];
string[i] = string[k];
string[k++] = t;
}
printf("the binary number is: %s\n", string);
}
For example, given -1234 (decimal), the output is -10011010010 (binary). It also handles both the extremes: INT_MAX, -INT_MAX and INT_MIN (assuming 32-bit int):
B = B to D
D = D to B
choose which one to convert to: D
enter decimal number to convert to binary: 2147483647
the binary number is: 1111111111111111111111111111111
B = B to D
D = D to B
choose which one to convert to: D
enter decimal number to convert to binary: -2147483647
the binary number is: -1111111111111111111111111111111
B = B to D
D = D to B
choose which one to convert to: D
enter decimal number to convert to binary: -2147483648
the binary number is: -10000000000000000000000000000000
If, on the other hand, you want the bit pattern corresponding to the value, then Joachim Pileborg's answer does that for you.
(It's C99 code because it declares variables at convenient points part way through a block, rather than at the start of a block as C89 requires.)
The simplest thing is probably to convert the string input to a proper integer (using e.g. strtol), and the convert that number to a string containing only ones and zeroes.
Something like:
/* Convert a (possibly signed) decimal number in a string to a long integer */
unsigned long number = (unsigned long) strtol(string, NULL, 10);
char output_string[65]; /* If longs are 64 bits, plus one for terminator */
char *output_ptr = output_string;
/* Start with the highest bit, go down to the lowest */
/* sizeof(long) is either 4 or 8 depending on 32 or 64 bit platforms */
/* Multiply with 8 to get the number of bits */
/* -1 because bits are numbered from 0 to 31 (or 63) */
for (int bit = (sizeof(unsigned long) * 8) - 1; bit >= 0; bit--)
{
/* Using right shift to get the current bit into the lowest position */
/* Doing bitwise AND to see if the lowest bit is a one or a zero */
/* Adding '0' makes a a printable ASCII value of a digit */
*output_ptr++ = ((number >> bit) & 1) + '0';
/* `*output_ptr` gets the value that `output_ptr` points to */
/* Then use the `++` operator to increase the pointer */
/* Now `output_ptr` points to the next character in `output_string` */
}
/* Terminate string */
*output_ptr = '\0';
printf("%ld in binary is %s\n", number, output_string);

Resources