-6

Please help me to sort out the error in the following program.I am not getting the correct output for the decimal part. Thanks in advance

#include<stdio.h>
#include<math.h>

main()
{
    int p,i,j,t,x;
    float n,sum,d;

    printf("enter the binary number");
    scanf("%f",&n);

    p=(int)n;
    d=n-p;

    i=0;
    while(p>0)
    {
        t=p%10;
        sum=sum+t*pow(2,i);
        p=p/10;
        i=i+1;
    }

    i=1;
    while(d>0.0)
    {
        d=d*10;
        x=(int)d;
        sum=sum+x*pow(2,-i);
        d=d-x;
        i=i+1;
    }

    printf("decimal value is %f",sum);
    getch();
}
Paul R
  • 208,748
  • 37
  • 389
  • 560
Aswin
  • 51
  • 1
  • 8
  • 6
    first get indent your code please – Grijesh Chauhan Jul 20 '13 at 19:24
  • 3
    @GrijeshChauhan Ah, those outraging expectations! :P –  Jul 20 '13 at 19:25
  • 4
    Please also state (a) what you expect the output to be, (b) what output you are actually getting and (c) what you have actually tried so far to debug this. – Paul R Jul 20 '13 at 19:27
  • 1
    Can you give some example inputs and outputs? – GWW Jul 20 '13 at 19:27
  • Your compiler should be trying to murder you for using scanf! – dans3itz Jul 20 '13 at 19:28
  • I'm gonna guess that the use of floating point numbers is to blame – tay10r Jul 20 '13 at 19:30
  • Not to mention default int return for `main()`. – Paul R Jul 20 '13 at 19:30
  • You never fully describe the problem your program is trying to solve. But, assuming you want the input for `100.11` to generate the output `4.75`, the fixes you need are to initialize `sum` to `0`, and figure out how to round the decimal computations correctly to adjust for the error of the floating point representation of the input provided. But, that is all hard. Treat your input as a string instead, and the computations are easier. – jxh Jul 20 '13 at 20:32
  • @jxh : yes I'm trying to get an output 4.75 for 100.11... I'm getting 4.000 for 100... but while I'm trying to convert with decimal part the "second while part" is not working...for 100.11 I'm getting 4.807510.. – Aswin Jul 21 '13 at 07:26
  • @jxh I have tried with treating the input as string and it worked fine... but still for academic interest i just need to know the error in the above codes I tried... – Aswin Jul 21 '13 at 07:36
  • @Aswin: You should put a more complete description of your problem in your posting. – jxh Jul 21 '13 at 08:08

2 Answers2

2

You're problem is that you're using float when you should be using int and you haven't initialized any of your variables. Change float to int and initialize your variables to 0 and your code will work.

The reason your code isn't working is because sum isn't initialized. When you use sum = sum + t * pow (2, i), you are adding an arbitrary number to the result in the first go around. sum could be anything before it's initialized (ie -1241232).

Even though the only variables that really need to be initialized are sum, d, and i, it's a good practice to initialize them anyway (better safe than sorry). In fact, initialized variables are a very common cause of errors. Initialize everything.

The floating point datatype is also causing problems in you code, in the second loop. When the user inputs a floating point number, like 110.1101, it gets approximated to another number (ie 110.110098) - this has to do with the limitation of the floating point datatype. In your second loop, with the input approximated to 110.1100998, the problem is caused in this statement:

sum = sum + x * pow (2.0f, -i);

Because x isn't 1 or 0 throughout the whole loop (sometimes 9 or 8, etc). What's more, the loop doesn't just iterate 4 times (1101), it does many more. This is because of this statement:

d = d * 10;

When d gets multiplied by 10, it goes from 0.100998 to about 1.00979 - not 1.00998 like you'd expect. These two discrepancies are what's causing your results to be erroneous when you input values more precise than a single digit.

Finally, here's some working code:

#include <stdio.h>
#include <math.h>

int main (){

    int p = 0, i = 0, j = 0, t = 0, x = 0;
    float n = 0.0f, sum = 0.0f, d = 0.0f;

    printf("enter the binary number: ");
    scanf("%f", &n);

    p = n;
    d = n - p;

    while (p > 0){ // never use the float datatype for iteration
        t = p % 10;
        sum = sum + t * pow (2.0f,i);
        p = p / 10;
        i = i + 1;
    }

    i = 1;

    while (d > 0.00001){
        d = d * 10;
        x = d;
        sum = sum + x * pow (2.0f, -i);
        d = d - x;
        i = i + 1;
    }

    printf ("decimal value is %f\n", sum);
    getchar ();
    return 0;
}
tay10r
  • 4,234
  • 2
  • 24
  • 44
  • Your version of the program doesn't do what the OP was originally trying to accomplish. – jxh Jul 20 '13 at 20:23
  • @jxh how so? It still converts binary to a decimal – tay10r Jul 20 '13 at 20:25
  • The input `10.1` should result in the output `2.5`. – jxh Jul 20 '13 at 20:26
  • @jxh thank you, I suppose that reflects the value in fully understanding the question – tay10r Jul 20 '13 at 20:31
  • You're welcome, +1'd. – jxh Jul 20 '13 at 20:38
  • @TaylorFlores: I have initialized variable sum as sum=0 and run again.. but the output is still not correct.. for eg: if I enter 110.1101 it should return 6.8125.. but the output I am getting is 7.274681.. I have tried your codes also but the result is same.. – Aswin Jul 21 '13 at 07:09
  • @Aswin I've updated my answer to explain why you're getting that result. The only fix for this is to except the input as a string, instead of a floating point datatype (as jxh has suggested). I highly recommend that. – tay10r Jul 21 '13 at 15:04
1

I am assuming you are expecting input of the form [01.]* with the constraint that there is only one decimal point. You are reading this input like a regular floating point number, but interpreting its decimal digits as binary digits and computing the decimal value.

main() should be declared int main (). getch() isn't a standard C call. You can use getchar().

You are probably getting crazy output because sum is not initialized to 0.

When you compute your fractional terms, you have to keep in mind that floating point representation is binary, and not all decimal numbers have an exact representation. So you need to perform rounding. Also, you are checking for d>0 as your stopping condition for your second loop, but floating point comparison is trickier than that. You can read this answer for a complete explanation as to why it is tricky, but you should basically do something like this:

    float err=.000001;
    while(d>err)
    {
        d=d*10;
        err=err*10;
        x=(int)(d+.5);
        /*...*/

The floating point complexity of your code can be reduced by reading your input as a string, and parsing that instead.

    char *n;
    char p[INPUT_MAX];
    char d[INPUT_MAX];
    char input[INPUT_MAX];
    float sum, p_sum = 0, d_sum = 0;
    int i;
    printf("enter the binary number: ");
    if (fgets(input, sizeof(input), stdin) == 0) {
        puts("no input!");
        exit(0);
    }
    n = strchr(input, '.');
    if (sscanf(input, "%[01]", p) == 1) {
        for (i = 0; p[i] != '\0'; ++i) {
            p_sum = 2*p_sum + (p[i] - '0');
        }
    }
    if (sscanf(n, ".%[01]", d) == 1) {
        for (i = strlen(d); i > 0; --i) {
            d_sum = (d_sum + (d[i-1] - '0'))/2;
        }
    }
    sum = p_sum + d_sum;
    printf("decimal value is %f\n",sum);
Community
  • 1
  • 1
jxh
  • 69,070
  • 8
  • 110
  • 193
  • I disagree with your fix regarding the loop evaluation. Floating point comparisons shouldn't be used at all for discrete comparisons – tay10r Jul 20 '13 at 20:04
  • @TaylorFlores: `d` is a `float` in the original program. It is used to compute the fractional part of the "binary" floating point number. – jxh Jul 20 '13 at 20:19
  • +1 for better inferring the intention of the OP – tay10r Jul 20 '13 at 20:33
  • Hi all.. what my problem is in the integer part I am getting the correct output(while I am entering 110 I am getting the output as 6.000 which is correct). But the second "while part" having some errors because while I am entering 110.1101 the actual output should be 6.8125 but I am getting 7.274681.. – Aswin Jul 21 '13 at 07:09
  • @Aswin: Please read over the first half of my answer. Because you are not rounding the error, `.1` may come to you as `.0999997` or something like that. Because of that, your code produces nonsensical output. – jxh Jul 21 '13 at 08:02