-6

请帮我解决以下程序中的错误。我没有得到正确的小数部分输出。提前致谢

#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();
}
4

2 回答 2

2

你的问题是当你应该使用 int 并且你没有初始化任何变量时你正在使用 float 。更改floatint初始化您的变量0,您的代码将起作用。

您的代码不起作用的原因sum是没有初始化。当您使用 时sum = sum + t * pow (2, i),您将在第一次运行时将任意数字添加到结果中。sum在初始化之前可以是任何东西(即-1241232)。

尽管真正需要初始化的唯一变量是sumdi,但无论如何初始化它们是一个好习惯(安全总比抱歉好)。事实上,初始化变量是一个非常常见的错误原因。初始化一切。

在第二个循环中,浮点数据类型也会导致代码出现问题。当用户输入一个浮点数时,比如 110.1101,它会近似为另一个数字(即 110.110098)——这与浮点数据类型的限制有关。在您的第二个循环中,输入近似为 110.1100998,问题是由以下语句引起的:

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

因为 x 不是10贯穿整个循环(有时是9or8等​​)。更重要的是,循环不仅仅迭代 4 次(1101),它还做了更多。这是因为这个声明:

d = d * 10;

d乘以 时10,它会从0.100998变为 about 1.00979-1.00998 不像你所期望的那样。当您输入比单个数字更精确的值时,这两个差异导致您的结果错误。

最后,这是一些工作代码:

#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;
}
于 2013-07-20T19:42:27.627 回答
1

我假设您期望输入的表单[01.]*具有只有一位小数点的约束。您正在像常规浮点数一样读取此输入,但将其十进制数字解释为二进制数字并计算十进制值。

main()应该声明int main ()getch()不是标准的 C 调用。您可以使用getchar().

您可能会得到疯狂的输出,因为sum未初始化为0.

在计算小数项时,您必须记住浮点表示是二进制的,并非所有十进制数都有精确的表示。所以你需要进行四舍五入。此外,您正在检查d>0您的第二个循环的停止条件,但浮点比较比这更棘手。您可以阅读此答案以获得有关它为何棘手的完整解释,但您基本上应该执行以下操作:

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

可以通过将输入作为字符串读取并对其进行解析来降低代码的浮点复杂性。

    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);
于 2013-07-20T19:50:47.333 回答